19 out of 97 rated this helpful Rate this topic

Lambda Expressions (C# Programming Guide)

Help us create the documentation that's most important to you!

Take this short, anonymous survey (10 to 15 minutes) to rank the importance of tasks that you perform when you use Microsoft developer technologies. Your feedback will help us create MSDN documentation that meets your needs. To provide feedback, go to the survey page. Thanks in advance!

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 int del(int i);
static void Main(string[] args)
{
    del myDelegate = x => x * x;
    int j = myDelegate(5); //j = 25
}

To create an expression tree type:

using System.Linq.Expressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Expression<del> myET = x => x * x;
        }
    }
}

The => operator has the same precedence as assignment (=) and is right-associative.

Lambdas are used in method-based LINQ queries as arguments to standard query operator methods such as Where.

When you use method-based syntax to call the Where method in the Enumerable class (as you do in LINQ to Objects and LINQ to XML) the parameter is a delegate type System.Func(Of T, TResult). A lambda expression is the most convenient way to create that delegate. When you call the same method in, for example, the System.Linq.Queryable class (as you do in LINQ to SQL) then the parameter type is an System.Linq.Expressions.Expression<Func> where Func is any Func delegates with up to sixteen input parameters. Again, a lambda expression is just a very concise way to construct that expression tree. The lambdas allow the Where calls to look similar although in fact the type of object created from the lambda is different.

In the previous example, notice that the delegate signature has one implicitly-typed input parameter of type int, and returns an int. The lambda expression can be converted to a delegate of that type because it also has one input parameter (x) and a return value that the compiler can implicitly convert to type int. (Type inference is discussed in more detail in the following sections.) When the delegate is invoked by using an input parameter of 5, it returns a result of 25.

Lambdas are not allowed on the left side of the is or as operator.

All restrictions that apply to anonymous methods also apply to lambda expressions. For more information, see Anonymous Methods (C# Programming Guide).

A lambda expression with an expression on the right side is called an expression lambda. Expression lambdas are used extensively in the construction of Expression Trees (C# and Visual Basic). An expression lambda returns the result of the expression and takes the following basic form:

(input parameters) => expression

The parentheses are optional only if the lambda has one input parameter; otherwise they are required. Two or more input parameters are separated by commas enclosed in parentheses:

(x, y) => x == y

Sometimes it is difficult or impossible for the compiler to infer the input types. When this occurs, you can specify the types explicitly as shown in the following example:

(int x, string s) => s.Length > x

Specify zero input parameters with empty parentheses:

() => SomeMethod()

Note in the previous example that the body of an expression lambda can consist of a method call. However, if you are creating expression trees that will be consumed in another domain, such as SQL Server, you should not use method calls in lambda expressions. The methods will have no meaning outside the context of the .NET common language runtime.

A statement lambda resembles an expression lambda except that the statement(s) is enclosed in braces:

(input parameters) => {statement;}

The body of a statement lambda can consist of any number of statements; however, in practice there are typically no more than two or three.

delegate void TestDelegate(string s);
…
TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); };
myDel("Hello");

Statement lambdas, like anonymous methods, cannot be used to create expression trees.

Many Standard query operators have an input parameter whose type is one of the Func(Of T, TResult) family of generic delegates. The Func(Of T, TResult) delegates use type parameters to define the number and type of input parameters, and the return type of the delegate. Func delegates are very useful for encapsulating user-defined expressions that are applied to each element in a set of source data. For example, consider the following delegate type:

public delegate TResult Func<TArg0, TResult>(TArg0 arg0)

The delegate can be instantiated as Func<int,bool> myFunc where int is an input parameter and bool is the return value. The return value is always specified in the last type parameter. Func<int, string, bool> defines a delegate with two input parameters, int and string, and a return type of bool. The following Func delegate, when it is invoked, will return true or false to indicate whether the input parameter is equal to 5:

Func<int, bool> myFunc = x => x == 5;
bool result = myFunc(4); // returns false of course

You can also supply a lambda expression when the argument type is an Expression<Func>, for example in the standard query operators that are defined in System.Linq.Queryable. When you specify an Expression<Func> argument, the lambda will be compiled to an expression tree.

A standard query operator, the Count method, is shown here:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);

The compiler can infer the type of the input parameter, or you can also specify it explicitly. This particular lambda expression counts those integers (n) which when divided by two have a remainder of 1.

The following method will produce a sequence that contains all the elements in the numbers array that are to the left of the 9, because that is the first number in the sequence that does not meet the condition:

var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);

This example shows how to specify multiple input parameters by enclosing them in parentheses. The method returns all the elements in the numbers array until a number is encountered whose value is less than its position. Do not confuse the lambda operator (=>) with the greater than or equal operator (>=).

var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index);

When writing lambdas, you often do not have to specify a type for the input parameters because the compiler can infer the type based on the lambda body, the underlying delegate type, and other factors as described in the C# Language Specification. For most of the standard query operators, the first input is the type of the elements in the source sequence. So if you are querying an IEnumerable<Customer>, then the input variable is inferred to be a Customer object, which means you have access to its methods and properties:

customers.Where(c => c.City == "London");

The general rules for lambdas are as follows:

  • The lambda must contain the same number of parameters as the delegate type.

  • Each input parameter in the lambda must be implicitly convertible to its corresponding delegate parameter.

  • The return value of the lambda (if any) must be implicitly convertible to the delegate's return type.

Note that lambda expressions in themselves do not have a type because the common type system has no intrinsic concept of "lambda expression." However, it is sometimes convenient to speak informally of the "type" of a lambda expression. In these cases the type refers to the delegate type or Expression type to which the lambda expression is converted.

Lambdas can refer to outer variables that are in scope in the enclosing method or type in which the lambda is defined. Variables that are captured in this manner are stored for use in the lambda expression even if variables would otherwise go out of scope and be garbage collected. An outer variable must be definitely assigned before it can be consumed in a lambda expression. The following example demonstrates these rules:

delegate bool D();
delegate bool D2(int i);

class Test
{
    D del;
    D2 del2;
    public void TestMethod(int input)
    {
        int j = 0;
        // Initialize the delegates with lambda expressions.
        // Note access to 2 outer variables.
        // del will be invoked within this method.
        del = () => { j = 10;  return j > input; };

        // del2 will be invoked after TestMethod goes out of scope.
        del2 = (x) => {return x == j; };
      
        // Demonstrate value of j:
        // Output: j = 0 
        // The delegate has not been invoked yet.
        Console.WriteLine("j = {0}", j);        // Invoke the delegate.
        bool boolResult = del();

        // Output: j = 10 b = True
        Console.WriteLine("j = {0}. b = {1}", j, boolResult);
    }

    static void Main()
    {
        Test test = new Test();
        test.TestMethod(5);

        // Prove that del2 still has a copy of
        // local variable j from TestMethod.
        bool result = test.del2(10);

        // Output: True
        Console.WriteLine(result);
           
        Console.ReadKey();
    }
}

The following rules apply to variable scope in lambda expressions:

  • A variable that is captured will not be garbage-collected until the delegate that references it goes out of scope.

  • Variables introduced within a lambda expression are not visible in the outer method.

  • A lambda expression cannot directly capture a ref or out parameter from an enclosing method.

  • A return statement in a lambda expression does not cause the enclosing method to return.

  • A lambda expression cannot contain a goto statement, break statement, or continue statement whose target is outside the body or in the body of a contained anonymous function.

For more information, see the C# Language Specification. The language specification is the definitive source for C# syntax and usage.

Did you find this helpful?
(2000 characters remaining)
Community Content Add
Annotations FAQ
Eternal Discussions.
I've been developing for almost twenty years from now. $0This is not the first time I see such contradictory opinions about some (relatively) new concept and/or technology.$0 $0I said "relatively", which is clear to those who visited research.microsoft.com, haskel.org, for those who met Knuth, Church and Turing.$0 $0$0 $0 $0Eternal questions include, as usual, on the first sight contradictory concepts; security vs productivity, readability vs effectiveness, and so on, and so on.$0 $0$0 $0 $0It is quite human to defy changes and progress, though.$0 $0$0 $0 $0However, with LINQ, you have a choice of not using it. Simply, don't.$0 $0$0 $0 $0The best programming language and/or concept is the one you are most productive with.$0 $0Stick with it, share your results, and give your best to human kind.$0 $0$0 $0 $0Kind regards.$0 $0$0 $0
Code is for humans
Every line of code I write is meant to be read by a human other than me.
I am not employed to write clever code. I am employed to write transparent, maintainable code for those that follow when I am gone.
Ultimately clever code is a false economy, and Lambdas sit right in that falsehood.

Beauty is Lambdas and LINQ together
I'm a student, learning c# and I'm in awe of the power achievable with code that is amazingly stylish and brief.  Consider the example below.  This is something I did for an exercise.  The exercise was only supposed to be for us to use indexers to return a list of cars based on certain criteria.  My first, naive, attempt repeated the loop, test, return list code in each indexer property.  I recognised this repetitive pattern and my 2nd, slightly less naive attempt had the predicate and LINQ with the doSearch but with explicitly declared private static functions to provide the comparator for each indexer.  Those functions had to take a params [] object argument due to the indexers all having different numbers and  types of arguments.

Finally, as you can hopefully see, the final implementation is simple, quite easy to quickly understand and with the ability of lambdas to capture local variables, in this case, the arguments to the indexers, all the delegate needed as an argument was the car we are testing.  Doing something like this with a purely iterative approach is much much uglier IMHO.

public class Show_Room : LinkedList<Car>
    {
        private delegate bool Predicate(Car a);
        public List<Car> this[string make]         {             get             {                 return doSearch(car => car.Make.ToLower() == make.ToLower());             }         }
        public List<Car> this[double price]         {             get             {                 return doSearch(car => car.Price == price);             }         }
        public List<Car> this[DateTime year, string model]         {             get             {                 return doSearch(car => car.Date_Made.Year == year.Year && car.Model.ToLower() == model.ToLower());             }         }
        public List<Car> this[double price, int qty]         {             get             {                 return doSearch(car => car.Price == price && car.In_Stock == qty);             }         }
        private List<Car> doSearch(Predicate pred)         {             var results = from c in this                            where pred(c)                            orderby c.Price                            select c;
            if (results.Count() == 0)                 throw new CarNotFoundException();
            return results.ToList();         }     }
Lambda expressions capture extra this pointer.

Lambda expressions capture extra this pointer, if lambda use local variable and static variable or method, and delegate created from instance method in the same method as lambda expression.

using System;
internal static class Test{
private static void Main(){
try{
Console.WriteLine("{0,10}: Start point",GC.GetTotalMemory(true));
LambdaTest1 test1=new LambdaTest1();
Console.WriteLine("{0,10}: LambdaTest1 created",GC.GetTotalMemory(true));
Func<int> func1=test1.GetFunc();
Console.WriteLine("{0,10}: LambdaTest1 GetFunc called",GC.GetTotalMemory(true));
GC.KeepAlive(test1);
test1=null;
Console.WriteLine("{0,10}: LambdaTest1 removed, memory freed",GC.GetTotalMemory(true));
GC.KeepAlive(func1);
func1=null;
Console.WriteLine("{0,10}: LambdaTest1 func removed",GC.GetTotalMemory(true));
LambdaTest2 test2=new LambdaTest2();
Console.WriteLine("{0,10}: LambdaTest2 created",GC.GetTotalMemory(true));
Func<int> func2=test2.GetFunc();
Console.WriteLine("{0,10}: LambdaTest2 GetFunc called",GC.GetTotalMemory(true));
GC.KeepAlive(test2);
test2=null;
Console.WriteLine("{0,10}: LambdaTest2 removed, memory not freed",GC.GetTotalMemory(true));
GC.KeepAlive(func2);
func2=null;
Console.WriteLine("{0,10}: LambdaTest2 func removed, memory freed",GC.GetTotalMemory(true));
}catch(Exception e){
Console.WriteLine(e);
}
Console.ReadKey(true);
}
private class LambdaTest1{
private static int staticI=1;
private byte[] data=new byte[100000000];
private void Instance(){}
internal Func<int> GetFunc(){
int localI=2;
//Action action=Instance;
return ()=>localI+staticI;
}
}
private class LambdaTest2{
private static int staticI=1;
private byte[] data=new byte[100000000];
private void Instance(){}
internal Func<int> GetFunc(){
int localI=2;
Action action=Instance;
return ()=>localI+staticI;
}
}
}
Answers to Why Lambdas?
Bottom line, the Lambda concept* is highly useful and well worth learning.  Arguing which language feature is better than another is like arguing which branch of math is best...  If you are trying to add up shopping list items you don't need Differential Calculus.  However, I would challenge any developer that thinks he/she doesn't need a particular feature to learn to use the feature fully first and then determine if it's applicable to the solution at hand.

Why Lambda?

Lambda Expressions can solve problems in varying ways.  One very limited example is this... You can utilize them to define logical parts and reuse them later.  If done well this can make the code that uses the defined expressions more readable...

Pretend this is contained in a library written by Lambda aware folks and provided to the front end team.

Func<string,string> safe = t => {
   if( String.IsNullOrWhitespace(t) ){
      return String.Empty;
   }else{
     return t;
  }
};

...and in our front side

Person person = new Person {
  FirstName = safe( recordSet["FirstName"]),
  LastName = safe( recordSet["LastName"]),
  ...
};

...instead of what I see commonly:

Person person = new Person();
person.FirstName = String.IsNullOrWhiteSpace(recordSet["FirstName"]) ? String.Empty : recordSet["FirstName"];
person.LastName = String.IsNullOrWhiteSpace(recordSet["FirstName"]) ? String.Empty : recordSet["FirstName"];

This is, admittedly, a bit of a silly example but it's a quick demonstration of how small, but repetitive logic could be cleaned up using a couple simple Lambda expression.  One side affect here is that if I every wanted to change the global default for an application I could in a single line instead of multiple places in the code.

*Lambda Expressions come from Lambda Calculus and were not invented by Microsoft just to confuse and fuddle developers who never learned more than simple imperative programming.
Smarter Code Vs Maintainable Code
I feel, we have to pick one of the 2. Smarter Code Vs Maintainable Code.

with lambda expressions, code can become compact, that inturn can make things eazier. For example I remember I once did a very complicated Grouping using Aggregate<> and lambda expressions, and the code was only 1 line to maintain. This single line could eazily beocme a project in itself, giving more than 300 lines of C# code to maintain. Its always right tool for right work that we have to pick carefully.

KS
Lambda's are useful at times....
I don't use lambda expressions a lot in my code, but I have found them useful in very specific (and rare) cases.

Let's say that you have a varible ListOfWidgets defined as List<Widget> and you want to find a Widget with a specific WidgetId.  This is how I would use it.

public Widget GetWidget(int widgetId)
{
    return ListOfWidgets.Find(rec => rec.WidgetId == widgetId);
}

This is very simple and should be relatively easy to understand.  It was hard to get used to the syntax, but for simple cases like these the one line of code rather than a for loop with an if condition actually is quicker to write and it is still easy to understand (for me at least).
C# capture extra local variables

C# compiler generate code what capture extra local variables:

using System;
using System.Collections.Generic;
using System.Linq;
internal static class Test{
private static Random random=new Random();
private static void Main(){
try{
Func<IEnumerable<byte>>[] array=new Func<IEnumerable<byte>>[1024];
for(int i=0;i<1024;++i){
Func<IEnumerable<byte>> ab,bc,ca;
F(out ab,out bc,out ca);
array[i]=ab;
}
Console.WriteLine(GC.GetTotalMemory(true));
GC.KeepAlive(array);
}catch(Exception e){
Console.WriteLine(e);
}
Console.ReadKey();
}
private static void F(out Func<IEnumerable<byte>> ab,out Func<IEnumerable<byte>> bc,out Func<IEnumerable<byte>> ca){
byte[] a=new byte[1024];
random.NextBytes(a);
byte[] b=new byte[1024];
random.NextBytes(b);
byte[] c=new byte[1024*1024];
random.NextBytes(c);
ab=()=>a.Concat(b);
bc=()=>b.Concat(c);
ca=()=>c.Concat(a);
}
}

C# compiler rewrite code like this:

using System;
using System.Collections.Generic;
using System.Linq;
internal static class Test{
private static Random random=new Random();
private static void Main(){
try{
Func<IEnumerable<byte>>[] array=new Func<IEnumerable<byte>>[1024];
for(int i=0;i<1024;++i){
Func<IEnumerable<byte>> ab,bc,ca;
F(out ab,out bc,out ca);
array[i]=ab;
}
Console.WriteLine(GC.GetTotalMemory(true));
GC.KeepAlive(array);
}catch(Exception e){
Console.WriteLine(e);
}
Console.ReadKey();
}
private static void F(out Func<IEnumerable<byte>> ab,out Func<IEnumerable<byte>> bc,out Func<IEnumerable<byte>> ca){
AnonymousClass1 anonymousClass1=new AnonymousClass1();
anonymousClass1.a=new byte[1024];
random.NextBytes(anonymousClass1.a);
anonymousClass1.b=new byte[1024];
random.NextBytes(anonymousClass1.b);
anonymousClass1.c=new byte[1024*1024];
random.NextBytes(anonymousClass1.c);
ab=anonymousClass1.LambdaExpression1;
bc=anonymousClass1.LambdaExpression2;
ca=anonymousClass1.LambdaExpression3;
}
private sealed class AnonymousClass1{
public byte[] a;
public byte[] b;
public byte[] c;
public IEnumerable<byte> LambdaExpression1(){
return a.Concat(b);
}
public IEnumerable<byte> LambdaExpression2(){
return b.Concat(c);
}
public IEnumerable<byte> LambdaExpression3(){
return c.Concat(a);
}
}
}

As you can see, "c" local variable was captured and preserved as part of AnonymousClass1 object, despite the fact that all delegates what use it are not preserved.
I am suggest to rewrite code like this:

using System;
using System.Collections.Generic;
using System.Linq;
namespace System{
public class CapturableLocalVariable<T>{
public T Value;
}
}
internal static class Test{
private static Random random=new Random();
private static void Main(){
try{
Func<IEnumerable<byte>>[] array=new Func<IEnumerable<byte>>[1024];
for(int i=0;i<1024;++i){
Func<IEnumerable<byte>> ab,bc,ca;
F(out ab,out bc,out ca);
array[i]=ab;
}
Console.WriteLine(GC.GetTotalMemory(true));
GC.KeepAlive(array);
}catch(Exception e){
Console.WriteLine(e);
}
Console.ReadKey();
}
private static void F(out Func<IEnumerable<byte>> ab,out Func<IEnumerable<byte>> bc,out Func<IEnumerable<byte>> ca){
CapturableLocalVariable<byte[]> a=new CapturableLocalVariable<byte[]>();
a.Value=new byte[1024];
random.NextBytes(a.Value);
CapturableLocalVariable<byte[]> b=new CapturableLocalVariable<byte[]>();
b.Value=new byte[1024];
random.NextBytes(b.Value);
CapturableLocalVariable<byte[]> c=new CapturableLocalVariable<byte[]>();
c.Value=new byte[1024];
random.NextBytes(c.Value);
ab=Tuple.Create(a,b).LambdaExpression1;
bc=Tuple.Create(b,c).LambdaExpression2;
ca=Tuple.Create(c,a).LambdaExpression3;
}
private static IEnumerable<byte> LambdaExpression1(this Tuple<CapturableLocalVariable<byte[]>,CapturableLocalVariable<byte[]>> context){
return context.Item1.Value.Concat(context.Item2.Value);
}
private static IEnumerable<byte> LambdaExpression2(this Tuple<CapturableLocalVariable<byte[]>,CapturableLocalVariable<byte[]>> context){
return context.Item1.Value.Concat(context.Item2.Value);
}
private static IEnumerable<byte> LambdaExpression3(this Tuple<CapturableLocalVariable<byte[]>,CapturableLocalVariable<byte[]>> context){
return context.Item1.Value.Concat(context.Item2.Value);
}
}

Now "c" local variable captured but not preserved (collected by garbage collector), as all delegate what use it not preserved in "Test.Main".

Lambda's are cool
Lambda's are cool. Try something like this (untested):   $0List.RemoveAll(word => word != word.ToLower()); $0 VS  $0foreach (var item in List) if (item != item.ToLower()) List.Remove(item);$0 This quite clearly removes any word from the list where the word contains a capital letter.  *(Where List is replaced with suitable populated List<string>).
Awkward syntax
Tthe Lambda expression syntax is awkward. Though it is powerful, it is not easily understood by programmers other than the one who wrote it. It takes some time to get comfortable with the syntax.
Using Lambda expression in c#.
By using lambda expression we make code more attractive as well as line of code is simple. So for developer point of view it is good to use lambda expression. Its a great feature introduce in .net. You will get a beginners article at this link
http://www.mindstick.com/Blog/181/Lambda%20Expression%20in%20c
This might be use ful.
It takes two to tango
OK Folks. As you might already know, it take two to tango. One of them is you, the other is Lambda.

Each one of us must individually decide whether to use it or not.

And I for one do not understand how a single line lambda expression is considered more readable than a simple while or for loop. May be in a couple of years both would mean the same to me but for now, I would stick on to the good 'ol 3 line forloop.
Another APL?
Very powerful, but very obscure.  Read through the above link for recursive lambda expressions.  Really?  REALLY??

By far, the greatest costs associated with software are in development and maintenance.  Do you really want that recursive lambda expression(s) for generating a simple factorial to be inserted in place of:

intfactorial(intn)
{
    if(n<=1)
        return1;
    else
        return  n*factorial(n-1);
}

Just because you can do something doesn't mean you should.  It reminds me of the old APL contest to see who could write the most obscure code for a specified function.  In the end, this will be wiped into "frameworks" or forgotten altogether.
Not for everyone
To be fair to the nay-sayers, this kind of programming is not a good fit for application level code. So, if that is all you do, go ahead and ignore it.
This belongs in framework and reusable component development, the kind of stuff that is rarely touched once it is created and tested.

And yes. If your standard for understandability is conditionals and loops only, please ignore this kind of stuff. Better still, stick to VB Script. ;)
Expressions - Lambda or Regular
Those Lambda haters: Do you love regular expressions?
Lambdas are usefull in some situations
I don't know what's with all that hate in the thread. Just don't use them if you don't want to. We can hardly call them new, it's (partially) just sintax sugar for writing delegates. Same old delegates that are here since the very begining,  verbose, ugly and all that.

One example that I can think of is that they are very useful for Execute Around pattern that Kent Beck described back in '97. That alone would be enough ,but there is much more to it than just that.
Functional programming can be useful
Lambda expressions are a concept borrowed from functional programming. It's just another way of doing things but one aimed as making the code more concise and adding the benefit that you're describing what you want, rather than how. (This is where comparisons to SQL shed some light although it's a limited metaphor.)

E.g. given a list of strings that might contain duplicates when case sensitivity is ignored, find all duplicate values. A procedural approach isn't complicated but would mean writing the iteration code and building up the list of results. The lambda approach defines an expression to return these by specifying just the logical test, not the iteration.

This might be a trivial example but the benefit grows as the problem gets more intricate. If unconvinced then do check out Jon Skeet's C# In Depth (which is well worth the effort anyway).
Useful!

Lambdas are, in my opinion, vital to making decent programs that handle much data, like lists. They need sorting, you might need to pick some members and move them to another list, etc. Plus, you really don't have to use them if you don't have to.

I personally find them a very good addition to the .NET languages.

Lambda Expressions & LINQ
... a solution to a problem that didn't exist.  A way to obfuscate tried and true, well-understood, efficient ways of writing code to access data.  Another layer of complexity we didn't need.  Microsoft rolls out something like this every 5 years or so, and has been doing so for the 25 years I've been a programmer.  Lamdas are like the Zune... when they came along, there was already a better way of doing things (the iPod).  Microsoft announced the death of the Zune today, and one can only hope the same announcement comes soon for Lambdas, LINQ, and everything associated with it. 

To the poster who wrote that as professionals, we need to learn new technology and adapt:  I agree.  But we also need the experience and wisdom to avoid jumping on every bandwagon that rolls through town.  Especially those with loose wheels and no sign of a competent driver.
There is nothing else better to use
What is all the hate about? If you are using LINQ to Objects than you have really no choice to use Lambda Expressions. MY ONLY PROBLEM WITH IT is that it is not much documentation on using it with LINQ.
Whats the benefit?
Just asking....how does lambda expression give you greater code re-usability? I mean if I had a named function in a library I can use it over and over again. But a lambda expression can only be used where its defined as its inline (am I wrong?). So, if its a one time use expression, why even bother to make it a  Lambda? Why not spell out the expression logic within the body? $0$0 $0 $0So instead of saying (x) => x*x and then calling it separately, why not just have x*x directly as part of the code? $0 $0$0 $0 $0Sorry....I am new to .NET so I might be misstating.$0
Adoption will come over time just like any other language syntax
The only bad part about language extenstions like these is that if a person encounters code that uses them and they are not up-to-speed on the extension, it can be difficult to understand the program flow.  The same can be said about any syntax.  If someone chooses to only use "if / else if / else", and not read up on "switch / case" statements, then they would not know how to interpret the code using a switch if it were encounterred in code that they did not write.  The functionality of a switch can be achieved using an if / else if / else statement, so why use it?  Possibly for the sake of readability or to reduce the amount of effort.  The same can be said of Lambda expressions.

Hooray for Lambas
I understand why many people find Lambdas confusing.  However, once you get the hang of them they are not at all difficult. 

They are very hand, too.  They let you create delegates with fewer lines of code, for one thing.  Fewer lines of code means fewer opportunities for mistakes and greater productivity.  They are also key to the LINQ technology, which, again, lets you do more with less effort.  In LINQ and elsewhere, Lambda expressions are a standard way to express almost any kind of query, without having to invent your own classes to do so.

If you want everything to be "simple" then go back to programming in C.   And forget about the .NET Framework because it's waaaay harder to master than C's good old standard libraries.  Throw out Windows and Web programming and go back to DOS, where you could always control what was going to happen next.

But if your goal is to be a true professional, then you must master the tools of your trade ... and stay up-to-date.  Doctors must keep up with the latest medical advances, auto mechanics must study up on the latest innovations from Detroit and Japan, and we programmers must put in the time to master the language innovations that will increase our productivity.  If you don't do it, there are plenty of people around the world who would love to take your place.

Besides, if you don't get pleasure out things like Lambdas, why are you even in this profession?  To me, they are elegant and fun.
Advertisement