Difference in conversion of anonymous method and lambda expression
Consider the following class
delegate void Moo(int a, int b, int c);
class A
{
public event Moo moo;
}
In case I want to create a handler for the moo event where I don't care about the 3 parameters needed by the event handler I can easily write it as
A a = new A();
a.moo += delegate { count++; };
However, in case I want to create the same handler with a lambda expression. I have to do it as
A a = new A();
a.moo += (a1,a2,a3) => count++;
There is no shortcut to this. I can't use say a.moo += () => count++;
The reason lies in the fact that both support a different set of conversions.
From C# 2.0 spec (§21.3 - Anonymous methods conversions)
An implicit conversion (§6.1) exists from an anonymous-method-expression to any compatible delegate type. If D is a delegate type, and A is an anonymous-method-expression, then D is compatible with A if and only if the following two conditions are met.
• First, the parameter types of D must be compatible with A:
o If A does not contain an anonymous-method-signature, then D may have zero or more parameters of any type, as long as no parameter of D has the out parameter modifier.
In C# 3.0 spec for Lambda expression conversion it sez
Specifically, a delegate type D is compatible with a lambda-expression L provided:
• D and L have the same number of parameters.
• If L has an explicitly typed parameter list, each parameter in D has the same type and modifiers as the
corresponding parameter in L.
• If L has an implicitly typed parameter list, D has no ref or out parameters.
...
In both the cases the lines marked in red indicate why one is different from the other.
Comments
Anonymous
July 09, 2007
Abhinaba,I found your blog over the weekend and based on your discussion of Lambda expressions, added it to my favorites. Good move on my part.I know you probably do this blog for fun, but I hope you don't get bored with talking about Lambda expressions, etc. for some time.BobHAnonymous
July 16, 2007
We can't instantiate interface object. and T is of type A which is nothing but a interface. That might be reason behind failing following statement: T t= new B() as T;Anonymous
December 23, 2007
Hi Abhinaba, Thanks for posting this. By the way, you might find this thread interesting, since it is (slightly) related to the point you made here. <a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2589975&SiteID=1&mode=1">http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2589975&SiteID=1&mode=1</a>Anonymous
December 23, 2007
Oops: that link is: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2589975&SiteID=1&mode=1