What's the Difference Between Anonymous Methods (C# 2.0) and Lambda Expressions (C# 3.0)

What's the difference between anonymous methods (C# 2.0) and lambda expressions (C# 3.0)?

The MSDN page on anonymous methods explains it

In versions of C# before 2.0, the only
way to declare a delegate was to use
named methods. C# 2.0 introduced
anonymous methods and in C# 3.0 and
later, lambda expressions supersede
anonymous methods as the preferred way
to write inline code. However, the
information about anonymous methods in
this topic also applies to lambda
expressions. There is one case in
which an anonymous method provides
functionality not found in lambda
expressions. Anonymous methods enable
you to omit the parameter list, and
this means that an anonymous method
can be converted to delegates with a
variety of signatures. This is not
possible with lambda expressions. For
more information specifically about
lambda expressions, see Lambda
Expressions (C# Programming Guide).

And regarding lambda expressions:

A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types.
All lambda expressions use the lambda operator =>, which is read as "goes to". The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block. The lambda expression x => x * x is read "x goes to x times x." This expression can be assigned to a delegate type as follows:

Anonymous methods vs. lambda expression

What is an anonymous method? Is it really anonymous? Does it have a name? All good questions, so let's start with them and work our way up to lambda expressions as we go along.

When you do this:

public void TestSomething()
{
Test(delegate { Debug.WriteLine("Test"); });
}

What actually happens?

The compiler first decides to take the "body" of the method, which is this:

Debug.WriteLine("Test");

and separate out that into a method.

Two questions the compiler now has to answer:

  1. Where should I put the method?
  2. What should the signature of the method look like?

The second question is easily answered. The delegate { part answers that. The method takes no parameters (nothing between delegate and {), and since we don't care about its name (hence the "anonymous" part), we can declare the method as such:

public void SomeOddMethod()
{
Debug.WriteLine("Test");
}

But why did it do all this?

Let's look at what a delegate, such as Action really is.

A delegate is, if we for a moment disregard the fact that delegates in .NET are actually linked list of multiple single "delegates", a reference (pointer) to two things:

  1. An object instance
  2. A method on that object instance

So, with that knowledge, the first piece of code could actually be rewritten as this:

public void TestSomething()
{
Test(new Action(this.SomeOddMethod));
}

private void SomeOddMethod()
{
Debug.WriteLine("Test");
}

Now, the problem with this is that the compiler has no way of knowing what Test actually does with the delegate it is given, and since one half of the delegate is a reference to the instance on which the method is to be called, this in the above example, we don't know how much data will be referenced.

For instance, consider if the above code was part of a really huge object, but an object that only live temporarily. Also consider that Test would store that delegate somewhere it would live for a long time. That "long time" would tie itself up to the life of that huge object as well, keeping a reference to that for a long time as well, probably not good.

So the compiler does more than just create a method, it also creates a class to hold it. This answers the first question, where should I put it?.

The code above can thus be rewritten as follows:

public void TestSomething()
{
var temp = new SomeClass;
Test(new Action(temp.SomeOddMethod));
}

private class SomeClass
{
private void SomeOddMethod()
{
Debug.WriteLine("Test");
}
}

That is, for this example, what an anonymous method is really all about.

Things get a bit more hairy if you start using local variables, consider this example:

public void Test()
{
int x = 10;
Test(delegate { Debug.WriteLine("x=" + x); });
}

This is what happens under the hood, or at least something very close to it:

public void TestSomething()
{
var temp = new SomeClass;
temp.x = 10;
Test(new Action(temp.SomeOddMethod));
}

private class SomeClass
{
public int x;

private void SomeOddMethod()
{
Debug.WriteLine("x=" + x);
}
}

The compiler creates a class, lifts all the variables that the method requires into that class, and rewrites all access to the local variables to be access to fields on the anonymous type.

The name of the class, and the method, are a bit odd, let's ask LINQPad what it would be:

void Main()
{
int x = 10;
Test(delegate { Debug.WriteLine("x=" + x); });
}

public void Test(Action action)
{
action();
}

If I ask LINQPad to output the IL (Intermediate Language) of this program, I get this:

// var temp = new UserQuery+<>c__DisplayClass1();
IL_0000: newobj UserQuery+<>c__DisplayClass1..ctor
IL_0005: stloc.0 // CS$<>8__locals2
IL_0006: ldloc.0 // CS$<>8__locals2

// temp.x = 10;
IL_0007: ldc.i4.s 0A
IL_0009: stfld UserQuery+<>c__DisplayClass1.x

// var action = new Action(temp.<Main>b__0);
IL_000E: ldarg.0
IL_000F: ldloc.0 // CS$<>8__locals2
IL_0010: ldftn UserQuery+<>c__DisplayClass1.<Main>b__0
IL_0016: newobj System.Action..ctor

// Test(action);
IL_001B: call UserQuery.Test

Test:
IL_0000: ldarg.1
IL_0001: callvirt System.Action.Invoke
IL_0006: ret

<>c__DisplayClass1.<Main>b__0:
IL_0000: ldstr "x="
IL_0005: ldarg.0
IL_0006: ldfld UserQuery+<>c__DisplayClass1.x
IL_000B: box System.Int32
IL_0010: call System.String.Concat
IL_0015: call System.Diagnostics.Debug.WriteLine
IL_001A: ret

<>c__DisplayClass1..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: ret

Here you can see that the name of the class is UserQuery+<>c__DisplayClass1, and the name of the method is <Main>b__0. I edited in the C# code that produced this code, LINQPad doesn't produce anything but the IL in the example above.

The less-than and greater-than signs are there to ensure that you cannot by accident create a type and/or method that matches what the compiler produced for you.

So that's basically what an anonymous method is.

So what is this?

Test(() => Debug.WriteLine("Test"));

Well, in this case it's the same, it's a shortcut for producing an anonymous method.

You can write this in two ways:

() => { ... code here ... }
() => ... single expression here ...

In its first form you can write all the code you would do in a normal method body. In its second form you're allowed to write one expression or statement.

However, in this case the compiler will treat this:

() => ...

the same way as this:

delegate { ... }

They're still anonymous methods, it's just that the () => syntax is a shortcut to getting to it.

So if it's a shortcut to getting to it, why do we have it?

Well, it makes life a bit easier for the purpose of which it was added, which is LINQ.

Consider this LINQ statement:

var customers = from customer in db.Customers
where customer.Name == "ACME"
select customer.Address;

This code is rewritten as follows:

var customers =
db.Customers
.Where(customer => customer.Name == "ACME")
.Select(customer => customer.Address");

If you were to use the delegate { ... } syntax, you would have to rewrite the expressions with return ... and so on, and they'd look more funky. The lambda syntax was thus added to make life easier for us programmers when writing code like the above.

So what are expressions?

So far I have not shown how Test has been defined, but let's define Test for the above code:

public void Test(Action action)

This should suffice. It says that "I need a delegate, it is of type Action (taking no parameters, returning no values)".

However, Microsoft also added a different way to define this method:

public void Test(Expression<Func<....>> expr)

Note that I dropped a part there, the .... part, let's get back to that 1.

This code, paired with this call:

Test(() => x + 10);

will not actually pass in a delegate, nor anything that can be called (immediately). Instead, the compiler will rewrite this code to something similar (but not at all like) the below code:

var operand1 = new VariableReferenceOperand("x");
var operand2 = new ConstantOperand(10);
var expression = new AdditionOperator(operand1, operand2);
Test(expression);

Basically the compiler will build up an Expression<Func<...>> object, containing references to the variables, the literal values, the operators used, etc. and pass that object tree to the method.

Why?

Well, consider the db.Customers.Where(...) part above.

Wouldn't it be nice if, instead of downloading all customers (and all their data) from the database to the client, looping through them all, finding out which customer has the right name, etc. the code would actually ask the database to find that single, correct, customer at once?

That's the purpose behind expression. The Entity Framework, Linq2SQL, or any other such LINQ-supporting database layer, will take that expression, analyze it, pick it apart, and write up a properly formatted SQL to be executed against the database.

This it could never do if we were still giving it delegates to methods containing IL. It can only do this because of a couple of things:

  1. The syntax allowed in a lambda expression suitable for an Expression<Func<...>> is limited (no statements, etc.)
  2. The lambda syntax without the curly brackets, which tells the compiler that this is a simpler form of code

So, let's summarize:

  1. Anonymous methods are really not all that anonymous, they end up as a named type, with a named method, only you do not have to name those things yourself
  2. It's a lot of compiler magic under the hood that moves things around so that you don't have to
  3. Expressions and Delegates are two ways to look at some of the same things
  4. Expressions are meant for frameworks that wants to know what the code does and how, so that they can use that knowledge to optimize the process (like writing a SQL statement)
  5. Delegates are meant for frameworks that are only concerned about being able to call the method

Footnotes:

  1. The .... part for such a simple expression is meant for the type of return value you get from the expression. The () => ... simple expression ... only allows expressions, that is, something that returns a value, and it cannot be multiple statements. As such, a valid expression type is this: Expression<Func<int>>, basically, the expression is a function (method) returning an integer value.

    Note that the "expression that returns a value" is a limit for Expression<...> parameters or types, but not of delegates. This is entirely legal code if the parameter type of Test is an Action:

    Test(() => Debug.WriteLine("Test"));

    Obviously, Debug.WriteLine("Test") doesn't return anything, but this is legal. If the method Test required an expression however, it would not be, as an expression must return a value.

C# Lambda expressions: Why should I use them?

Lambda expressions are a simpler syntax for anonymous delegates and can be used everywhere an anonymous delegate can be used. However, the opposite is not true; lambda expressions can be converted to expression trees which allows for a lot of the magic like LINQ to SQL.

The following is an example of a LINQ to Objects expression using anonymous delegates then lambda expressions to show how much easier on the eye they are:

// anonymous delegate
var evens = Enumerable
.Range(1, 100)
.Where(delegate(int x) { return (x % 2) == 0; })
.ToList();

// lambda expression
var evens = Enumerable
.Range(1, 100)
.Where(x => (x % 2) == 0)
.ToList();

Lambda expressions and anonymous delegates have an advantage over writing a separate function: they implement closures which can allow you to pass local state to the function without adding parameters to the function or creating one-time-use objects.

Expression trees are a very powerful new feature of C# 3.0 that allow an API to look at the structure of an expression instead of just getting a reference to a method that can be executed. An API just has to make a delegate parameter into an Expression<T> parameter and the compiler will generate an expression tree from a lambda instead of an anonymous delegate:

void Example(Predicate<int> aDelegate);

called like:

Example(x => x > 5);

becomes:

void Example(Expression<Predicate<int>> expressionTree);

The latter will get passed a representation of the abstract syntax tree that describes the expression x > 5. LINQ to SQL relies on this behavior to be able to turn C# expressions in to the SQL expressions desired for filtering / ordering / etc. on the server side.

C#: Anonymous method vs Named method

A named method is a method you can call by its name (e.g. it is a function that has a name). For example, you have defined a function to add two numbers:

int f(int x, int y)
{
return x+y;
}

You would call this method by its name like so: f(1, 2);.

Anonymous method is a method that is passed as an argument to a function without the need for its name. These methods can be constructed at runtime or evaluated from a lambda expression at compile time.

These methods are often used in LINQ queries, for example:

int maxSmallerThan10 = array.Where(x => x < 10).Max();

The expression x => x < 10 is called a lambda expression and its result is an anonymous function that will be run by the method Where.

If you are a beginner, I would suggest you first read about more basic stuff. Check out the following links:

  • http://www.completecsharptutorial.com/
  • http://www.csharp-station.com/tutorial.aspx
  • http://www.homeandlearn.co.uk/csharp/csharp.html

Why Local Functions generate IL different from Anonymous Methods and Lambda Expressions?

Anonymous methods stored in delegates may be called by any code, even code written in different languages, compiled years before C# 7 came out, and the CIL generated by the compiler needs to be valid for all possible uses. This means in your case, at the CIL level, the method must take no parameters.

Local methods can only be called by the same C# project (from the containing method, to be more specific), so the same compiler that compiles the method will also be handled to compile all calls to it. Such compatibility concerns as for anonymous methods therefore don't exist. Any CIL that produces the same effects will work here, so it makes sense to go for what's most efficient. In this case, the re-write by the compiler to enable the use of a value type instead of a reference type prevents unnecessary allocations.

delegate keyword vs. lambda notation

Short answer : no.

Longer answer that may not be relevant:

  • If you assign the lambda to a delegate type (such as Func or Action) you'll get an anonymous delegate.
  • If you assign the lambda to an Expression type, you'll get an expression tree instead of a anonymous delegate. The expression tree can then be compiled to an anonymous delegate.

Edit:
Here's some links for Expressions.

  • System.Linq.Expression.Expression(TDelegate) (start here).
  • Linq in-memory with delegates (such as System.Func) uses System.Linq.Enumerable. Linq to SQL (and anything else) with expressions uses System.Linq.Queryable. Check out the parameters on those methods.
  • An Explanation from ScottGu. In a nutshell, Linq in-memory will produce some anonymous methods to resolve your query. Linq to SQL will produce an expression tree that represents the query and then translate that tree into T-SQL. Linq to Entities will produce an expression tree that represents the query and then translate that tree into platform appropriate SQL.

Difference between various ways of instantiating a delegate (FuncT, T)?

They're all the same. The first two are examples of anonymous methods. The last is an example of a lambda expression. Anonymous methods and lambda expressions are collectively called anonymous functions.

Anonymous methods were introduced in C# 2; lambda expressions were introduced in C# 3 and mostly superseded anonymous methods. Note that lambda expressions can also be converted to expression trees which represent the code as data rather than IL, as well as delegates.

Note that Func<TResult>, Func<T, TResult> etc are just examples of delegate types. You can convert anonymous functions to any compatible delegate type. For example:

public delegate int Foo(string x);

Foo foo = text => text.Length;

Difference between creating an event and anonymous method in c#

the main difference in your example is the structure of the method that will be performed. In the first case:

  1. timer.Tick += new EventHandler(timer_Tick); //event

the method timer_Tick looks like this:

public void timer_Tick(object sender, EventArgs e)
{

}

so you can use the parameters object sender and EventArgs e. What you actually do here is to call the constructor of EventHandler and you pass a delegate/pointer to a method into it.

Although this structure is given by the Tick property in your second case:


  1. timer.Tick += delegate {/to perform my operations on tick/}; //anonymous method

you create an anonymous method and actually hide the parameter with the delegate keyword and you have no access to them. Also you will not be able to call this method from somewhere else. You cannot simulate the firing of the event and you cannot reuse the code.

Here you could use a lambda expression to actually specify the parameters so that you can have access to them:

timer.Tick += (s, e) => { };

The third case:

timer.Tick += Timer_Tick;

is a short version of the first case. Here Visual Studio will infer the correct structure of the method for you without specifying the type of the event. If the method Timer_Tick that you implement will not match the the structure demanded by Tick the compiler will complain!

Example:

Sample Image

The delegate Tick is of type EventHandler . This typespecifies the structure that I wrote in the first case above, you will see it in the documentation. If (as you can see in the picture) the structures of the delegate Tick and the structure of the Timer_Tick method do not match you have an error. Note that in this expression:

timer.Tick += Timer_Tick;

Timer_Tick is just a delegate/a pointer to the method in question which has to be implemented!

For fundamental differences between delegates and events please have a look at this article and this acticle

What is the difference between C# versions like ver 2.0 and ver 3.0?

Many new features support the introduction of LINQ (they can be used in many different contexts, but they are very useful in the context of LINQ).

I strongly suggest you read Jon Skeet's C# in Depth for a detailed explanation of each new feature.



Related Topics



Leave a reply



Submit