So I'm working with code in which there are two object that contain each other, inside a list of which I do not know the contents of until runtime. I have a function that needs to convert the first object to a third object, but to do such I need to convert the second object aswell, however to do that I will need the convert the first, and here is the chicken and the egg problem.
Problem Example
namespace chicken // Also I like formatting my code like this, so don't judge me
{
public class Object1 { // Object One and Two are of the same class
public List<dynamic> contents = new List<dynamic>();
public Object1() {}
public Object1(List<dynamic> contents) {
this.contents = contents;
}
}
public class Object3 {
public string name;
public Object3 friend;
public string pet;
public Object3(List<dynamic> converted) {
this.name = converted[0];
this.friend = converted[1];
this.pet = converted[2];
}
}
public class Program {
public static void Main(string[] args) {
Object1 object1 = new Object1(); // Just to create the problem, they don't
Object1 object2 = new Object1(); // get created like this in the actual code
object1.contents = new List<dynamic> {
"Steve Johnson", // This is example data, this order is supposed to be unknown
object2,
"Biscut",
};
object2.contents = new List<dynamic> {
"Bob Smith",
object1,
"Tiny",
};
Object3 final = convert(object1); // Runs the conversion function
}
public static Object3 convert(Object1 obj) {
List<dynamic> converted = new List<dynamic>(); // I need a sanitized list for Object3
for (int i = 0; i < obj.contents.Count; i++) {
if (obj.contents[i] is Object1) {
converted.Add(convert(obj.contents[i])); // Causes infinite loop due to chicken and egg problem
continue;
} converted.Add(obj.contents[i]);
}
Object3 object3 = new Object3(converted); // Again the list order is unknown
return object3;
}
}
}
I've tried using references, where there is a tunnel object and 'Object3' passes references to it's varibles to it, so I can semi construct Object3, put it in a cache, pass it to object 2 to convert it, then put in the values though the tunnel object containing the references. This got to complicated and I honestly don't know what to do without having an empty constuctor for Object 3.
The problem you're describing can be simplified down to this:
In the following code, how can we make it so Node
a
referencesb
andb
referencesa
?You already hit on the solution: allow a
Node
to be constructed without all of its possible objects, so you can construct the Nodes first, and then insert them where they belong. It sounds like you don't want to give Node ("Object3") a default constructor, but the way you've implemented it at the moment, it should still be possible to add values after the fact, if you can add to its items list after its construction.If that will work for you, then the rest is just the details you've described:
It may be complicated, but that's pretty much what has to happen.
If, for some reason, you need your Object3 class structure to be immutable, so you cannot change its contents after its construction, then you're at an impasse: your requirements are clearly impossible. You're defining an object that must be constructed with all its dependencies, but its dependencies need it to be constructed before they can be constructed.