4

After reading this related answer -still I have a question

A lambda expression is an unnamed method written in place of a delegate instance. The compiler immediately converts the lambda expression to either:

  • A delegate instance.
  • An expression tree, of type Expression, representing the code inside the lambda expression in a traversable object model.

But When will it convert it do a delegate instance -- and when when it will convert it to expression tree ? ( didn't find related info on that one)

Not much of a related code - just tried to played with it - obviously both a matching. I didn't think so because I thought one would be a better match .

void Main()
{
     Foo( () => 0 );
}
  void Foo(Func<int > action)
{
    Console.WriteLine("1");
}

  void Foo(Expression<Func<int>> func)
{
    Console.WriteLine("2");
}

This will result in error (ambiguous between the following methods or properties)

Community
  • 1
  • 1
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • Not sure I understand. The same will go if you used your own delegate, say `delegate int Blah()` and have `void Foo(Blah blah)`. – leppie Apr 23 '14 at 10:47
  • @leppie the code is from what Jon wrote in the link , and I tried to play with it a bit. im just asking what makes a compiler translate it to delegate instance VS expression tree – Royi Namir Apr 23 '14 at 10:48
  • 2
    It will convert to whichever form you've effectively asked it to. Your code is ambiguous because it could convert to either `Func` or `Expression>` and neither conversions is deemed "better". It's not clear what you're asking. – Jon Skeet Apr 23 '14 at 10:49
  • @JonSkeet Are you saying that the context is what makes the compiler decide ? for example linq-2-sql will convert it to expression tree...? – Royi Namir Apr 23 '14 at 10:50
  • Personally, I would not even bother with this kind of overload. Just give it a different name, problem solved ;p – leppie Apr 23 '14 at 10:51
  • @RoyiNamir: No, Jon is saying it will be ambiguous in any context. LINQ uses a differentiator (`IEnumerable` and `IQueryable`) to do the disambiguation. – leppie Apr 23 '14 at 10:52
  • @leppie I know. I asked about the decision whether to convert it to expression tree VS delegate instance. forget my code – Royi Namir Apr 23 '14 at 10:53
  • @RoyiNamir: No, it's got nothing to do with LINQ to SQL - it's whether you're trying to convert the lambda expression to an `Expression<...>` or a delegate type. In your case, you've got valid conversions to both due to the overload.# – Jon Skeet Apr 23 '14 at 10:55

1 Answers1

5

It converts to whichever type you've asked it to. For example:

Func<int> del = () => 0; // Conversion to delegate
Expression<Func<int>> expression = () => 0; // Conversion to expression tree

In your case, you're asking the compiler to consider conversions to both forms, because of overloading. If you removed the Foo(Expression<Func<int>> func) method, the code would be valid and the compiler would convert the lambda expression to a delegate. If you removed the other method instead, the code would be valid and the compiler would convert the lambda expression to an expression tree.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194