views:

94

answers:

2

Is there any way to create anonymous type that references instances of itself?

var root = new { Name = "Root", Parent = ??? };
var child = new { Name = "Child", Parent = root };
var childOfChild = new { Name = "Grand child", Parent = child };

For example, we can reference delegate from itself:

Action run = null;
run = () => run();

Another example, we can create generic Stack of anonymous types:

static Stack<T> CreateStack<T>(params T[] values)
{
    var stack = new Stack<T>();

    foreach (var value in values)
        stack.Add(value);

    return stack;
}

Can you think of any ways to reference anonymous type from itself?

+5  A: 

Anonymous types in C# are immutable. Therefore all of their field values must have been present before the creation of the object and will never change. And therefore it is impossible to have a directly circular referencing anonymous type in C#.

Anonymous types in VB are mutable; you could probably figure out some way to do it in VB.

There might be a way to make an anonymous type indirectly reference itself, by, say, containing a delegate that when invoked, returns the instance of the anonymous type. I don't see any way off the top of my head to easily do that, but I also don't see a proof that doing so is impossible. Give it some thought and see what you come up with!

I assume this question is for entertainment purposes only. If you want to make a circularly-referential object, please make a nominal type.

Eric Lippert
My structure is immutable. Root has null as parent, direct root children reference Root, etc.
Konstantin Spirin
I've renamed question for clarity
Konstantin Spirin
+1  A: 

It seemed... that the C# compiler will simply refuses to infer the type recursively. Take this sample code for example:

(From @Eric: Correct; the type inference engine requires that all the "input" types of a lambda be known before the "output" type of the lambda is inferred)

public void Run()
{
  var k = Generator((str, parent) => new {
    Name = str,
    Parent = parent
  });
}

public Func<string, T, T> Generator<T>(Func<string, T, T> generator)
{
  return (str, obj) => generator(str, obj);
}

This snippet fails to compile with an error that the compiler cannot infer the <T> to use with Generator<T>... thus I think it's impossible.

chakrit
I've created new class already and asked on SO to check if my original task was impossible or not.
Konstantin Spirin
Interesting idea with generator!
Konstantin Spirin
Correct; the type inference engine requires that all the "input" types of a lambda be known before the "output" type of the lambda is inferred.
Eric Lippert