Problem
Is there a difference between: once it’s been compiled and: once it’s been compiled?
delegate { x = 0; }
and
() => { x = 0 }
?
Asked by MojoFilter
Solution #1
No, to put it simply.
A longer response that may or may not be useful:
Here are some Expressions-related links.
Answered by Amy B
Solution #2
I loved Amy’s response, but I was afraid I’d be too picky. “Once it is compiled,” states the query, implying that both phrases have been compiled. How could they both compile, but one as a delegate and the other as an expression tree? It’s a tough one because you have to leverage another characteristic of anonymous methods that lambda expressions don’t have. Any delegate type returning void and without any out parameters is compatible with an anonymous method specified without any parameter list. We should be able to design two overloads using this information to make the expressions completely unambiguous but quite different.
However, tragedy strikes! You can’t convert a lambda expression with a block body into an expression in C# 3.0, and you can’t convert a lambda expression with an assignment in the body into an expression either (even if it is used as the return value). With C# 4.0 and.NET 4.0, which allow for more expression in an expression tree, this may change. In other words, the two will almost always be converted to the same item using the examples MojoFilter provided. (In a moment, I’ll give you more information.)
However, if we edit the bodies slightly, we may use the delegate parameters trick:
using System;
using System.Linq.Expressions;
public class Test
{
static void Main()
{
int x = 0;
Foo( () => x );
Foo( delegate { return x; } );
}
static void Foo(Func<int, int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
static void Foo(Expression<Func<int>> func)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
But hold on! If we’re clever enough, we can distinguish between the two without needing expression trees. The overload resolution principles are used in the case below (and the anonymous delegate matching trick)…
using System;
using System.Linq.Expressions;
public class Base
{
public void Foo(Action action)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
public class Derived : Base
{
public void Foo(Action<int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
int x = 0;
d.Foo( () => { x = 0; } );
d.Foo( delegate { x = 0; } );
}
}
Ouch. Remember, a small kitten starts sobbing every time you overload a method inherited from a base class.
Answered by Jon Skeet
Solution #3
There is no difference between the two examples above.
The expression:
() => { x = 0 }
It can’t be compiled as an expression tree because it’s a Lambda expression with a statement body. It doesn’t even build because a semicolon is required after 0:
() => { x = 0; } // Lambda statement body
() => x = 0 // Lambda expression body, could be an expression tree.
Answered by Olmo
Solution #4
Amy B is entirely correct. It’s worth noting that there are several benefits to employing expression trees. The expression tree will be examined by LINQ to SQL and converted to SQL.
You can also use refactoring-safe tactics with lamdas and expression trees to effectively give the names of class members to a framework. This is exemplified by Moq.
Answered by Daniel Plaisted
Solution #5
There’s an important distinction to make.
Example:
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(delegate
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
And I use lambda instead: (error)
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(()=>
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
Answered by Án Bình Trọng
Post is based on https://stackoverflow.com/questions/299703/delegate-keyword-vs-lambda-notation