19

I'm trying to learn C#'s restrictions on an anonymous type. Consider the following code:

  var myAwesomeObject = new {
      fn1 = new Func<int>(() => { return 5; }),
      fn2 = () => { return 5; } 
  };

So we've got two properties that are actually functions:

  • fn1: A Func<int> that returns 5.
  • fn2: A lambda function that returns 5.

The C# compiler is happy to work with fn1, but complains about fn2 :

cannot assign lambda expression to anonymous type property.

Can someone explain why one is ok but the other is not?

Nasreddine
  • 36,610
  • 17
  • 75
  • 94
Stephen Gross
  • 5,274
  • 12
  • 41
  • 59
  • 3
    The compiler won't find a type that matches the anonymous method. It will coerce or use a type, if you use the anonymous method in a context where such a type can be determined, like in a method call, but in this case it won't pick a matching type. You have the same problem if you go: `var fn2 = () => { return 5; };` – Lasse V. Karlsen Nov 14 '11 at 21:52
  • The C# compiler doesn’t know if the lambda is meant to be a delegate or an expression tree. The solution is to instantiate the one you want to create. – Joe Nov 14 '11 at 21:55
  • 2
    @Thomas is right, but here's a more complete answer from Eric Lippert: http://stackoverflow.com/questions/4965576/c-sharp-why-cant-an-anonymous-method-be-assigned-to-var/4966409#4966409 – Adam Rackis Nov 14 '11 at 22:02

1 Answers1

22

Because there is no way for the compiler to know the type of () => { return 5; }; it could be a Func<int>, but it could also be any other delegate with the same signature (it could also be an expression tree). That's why you have to specify the type explicitly.

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • Ah... So it's a type inference problem. What's your recommendation for the most elegant code in this example? Is there anything I can do to refine the fn1 definition? – Stephen Gross Nov 14 '11 at 21:53
  • 2
    @StephenGross, well, you can also cast the lambda to the delegate type: `fn1 = (Func)(() => { return 5; })`; but I prefer the explicit delegate creation, like you did in your question. – Thomas Levesque Nov 14 '11 at 22:00
  • Even more, it might not be a delegate at all; it could be an `Expression>`! – Gabe Nov 14 '11 at 22:02