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 (4)

  1. oldgeek says:

    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.

    BobH

  2. nitin sohani says:

    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;

  3. John Rusk says:

    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&gt;