Delegate Keyword VS. Lambda Notation

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.

What is the difference between lambdas and delegates in the .NET Framework?

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.

  1. A normal method is defined in a "statement" and tied to a permanent name, whereas a lambda is defined "on the fly" in an "expression" and has no permanent name.
  2. Some lambdas can be used with .NET expression trees, whereas methods cannot.

A delegate is defined like this:

delegate Int32 BinaryIntOp(Int32 x, Int32 y);

A variable of type BinaryIntOp can have either a method or a labmda assigned to it, as long as the signature is the same: two Int32 arguments, and an Int32 return.

A lambda might be defined like this:

BinaryIntOp sumOfSquares = (a, b) => a*a + b*b;

Another thing to note is that although the generic Func and Action types are often considered "lambda types", they are just like any other delegates. The nice thing about them is that they essentially define a name for any type of delegate you might need (up to 4 parameters, though you can certainly add more of your own). So if you are using a wide variety of delegate types, but none more than once, you can avoid cluttering your code with delegate declarations by using Func and Action.

Here is an illustration of how Func and Action are "not just for lambdas":

Int32 DiffOfSquares(Int32 x, Int32 y)
{
return x*x - y*y;
}

Func<Int32, Int32, Int32> funcPtr = DiffOfSquares;

Another useful thing to know is that delegate types (not methods themselves) with the same signature but different names will not be implicitly casted to each other. This includes the Func and Action delegates. However if the signature is identical, you can explicitly cast between them.

Going the extra mile.... In C# functions are flexible, with the use of lambdas and delegates. But C# does not have "first-class functions". You can use a function's name assigned to a delegate variable to essentially create an object representing that function. But it's really a compiler trick. If you start a statement by writing the function name followed by a dot (i.e. try to do member access on the function itself) you'll find there are no members there to reference. Not even the ones from Object. This prevents the programmer from doing useful (and potentially dangerous of course) things such as adding extension methods that can be called on any function. The best you can do is extend the Delegate class itself, which is surely also useful, but not quite as much.

Update: Also see Karg's answer illustrating the difference between anonymous delegates vs. methods & lambdas.

Update 2: James Hart makes an important, though very technical, note that lambdas and delegates are not .NET entities (i.e. the CLR has no concept of a delegate or lambda), but rather they are framework and language constructs.

Difference between Func with delegate and lambda expression

They're the same, basically. They're both anonymous functions in C# specification terminology.

Lambda expressions are generally more concise, and can also be converted to expression trees, which are crucial for out-of-process LINQ.

Anonymous methods allow you to drop the parameter list if you don't care. For example:

EventHandler handler = delegate { 
Console.WriteLine("Sender and args don't matter");
};

Given how rarely the latter point is required, anonymous methods are becoming an endangered species in modern C#. Lambda expressions are much more common.

Understanding Lambda expressions and delegates

Delegates are methods that you can use as variables, like strings etc. For example you can declare a delegate method with one argument:

delegate void OneArgumentDelegate(string argument);

It doesn't do anything, much like an interface. If you have a method in any class with one argument like this:

void SomeMethod(string someArgument) {}

It matches the signature of the delegate, and thus can be assigned to a variable of its type:

OneArgumentDelegate ThisIsAVariable = new OneArgumentDelegate(SomeMethod);
OneArgumentDelegate ThisIsAlsoAVariable = SomeMethod; // Shorthand works too

These can then be passed as arguments to methods and invoked, like so:

void Main()
{
DoStuff(PrintString);
}

void PrintString(string text)
{
Console.WriteLine(text);
}

void DoStuff(OneArgumentDelegate action)
{
action("Hello!");
}

This will output Hello!.

Lambda expressions are a shorthand for the DoStuff(PrintString) so you don't have to create a method for every delegate variable you're going to use. You 'create' a temporary method that's passed on to the method. It works like this:

DoStuff(string text => Console.WriteLine(text)); // single line
DoStuff(string text => // multi line
{
Console.WriteLine(text);
Console.WriteLine(text);
});

Lambda expressions are just a shorthand, you might as well create a seperate method and pass it on. I hope you understand it better now ;-)

Lambda expression vs anonymous methods

Yes, lambda expressions are just very special anonymous methods.

However, there are some deep differences. Start with Eric Lippert's Lambda Expression vs. Anonymous Methods, Part One and continue to the rest of the series.

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:

Delegate return type different with lambda function

The return type of a lambda expression is not inferred from what the lambda acutally returns, but from the type it is assigend to. I.e., you can not assign a lambda like this (except when generic type parameters are involed; see comments of Eric Lippert):

// This generates the compiler error:
// "Cannot assign lambda expression to an implicitly-typed variable".
var lambda = () => new Foo();

You must always do something like this (lambdas are always assigned to a delegate type):

Func<MyType> lambda = () => new Foo();

Therefore in Test(() => new Foo()); the return type of the lambda is determined from the type of the parameter it is assigned to (IThing, the return type of ThingCreator).

In Test(Foo.Create); you don't have a lambda at all, but a method declared as public static Foo Create() .... Here the type is specified explicitly and is Foo (it makes no difference whether it is a static or instance method).



Related Topics



Leave a reply



Submit