Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between new Action() and a lambda?

So when I write something like this

Action action = new Action(()=>_myMessage = "hello"); 

Refactor Pro! Highlights this as a redundant delegate creation and allows me to to shorten it to

Action action = () => _myMessage="hello"; 

And this usually works great. Usually, but not always. For example, Rhino Mocks has an extension method named Do:

IMethodOptions<T> Do(Delegate action); 

Here, passing in the first version works, but the second doesn't. What exactly is going on under the covers here?

like image 880
George Mauer Avatar asked Apr 19 '09 19:04

George Mauer


People also ask

What is the difference between lambdas and delegates?

They are actually two very different things. "Delegate" is actually the name for a variable that holds a reference to a method or a lambda, and a lambda is a method without a permanent name. Lambdas are very much like other methods, except for a couple subtle differences.

Why do we use lambda expression in C#?

Lambda expressions in C# are used like anonymous functions, with the difference that in Lambda expressions you don't need to specify the type of the value that you input thus making it more flexible to use. The '=>' is the lambda operator which is used in all lambda expressions.

What is lambda expression in LINQ?

Advertisements. The term 'Lambda expression' has derived its name from 'lambda' calculus which in turn is a mathematical notation applied for defining functions. Lambda expressions as a LINQ equation's executable part translate logic in a way at run time so it can pass on to the data source conveniently.

What is a lambda expression in Java?

A lambda expression is a short block of code which takes in parameters and returns a value. Lambda expressions are similar to methods, but they do not need a name and they can be implemented right in the body of a method.


1 Answers

The first version is effectively doing:

Action tmp = () => _myMessage = "hello"; var action = new Action(tmp); 

The problem you're running into is that the compiler has to know what kind of delegate (or expression tree) the lambda expression should be converted into. That's why this:

var action = () => _myMessage="hello"; 

actually doesn't compile - it could be any delegate type with no parameters and either no return value or the same return type as _myMessage (which is presumably string). For instance, all of these are valid:

Action action = () => _myMessage="hello"; Func<string> action = () => _myMessage="hello"; MethodInvoker action = () => _myMessage="hello"; Expression<Action> = () => _myMessage="hello"; // etc 

How could the C# compiler work out what type action was meant to be, if it were declared with var?

The simplest way to get round this when calling a method (for your Rhino Mocks example) is to cast:

methodOptions.Do((Action) (() => _myMessage = "hello")); 
like image 111
Jon Skeet Avatar answered Oct 11 '22 13:10

Jon Skeet