C Sharp TutorialC Sharp .NET Compiler Platform (Roslyn)C Sharp 3.0 FeaturesC Sharp 4.0 FeaturesC Sharp 5.0 FeaturesC Sharp 6.0 FeaturesC Sharp 7.0 FeaturesC Sharp Access ModifiersC Sharp Access network shared folder with username and passwordC Sharp Accessing DatabasesC Sharp Action FiltersC Sharp Aliases of built-in typesC Sharp an overview of collectionsC Sharp Anonymous typesC Sharp ArraysC Sharp ASP.NET IdentityC Sharp AssemblyInfo.cs ExamplesC Sharp Async-AwaitC Sharp Async/await, Backgroundworker, Task and Thread ExamplesC Sharp Asynchronous SocketC Sharp AttributesC Sharp Authentication handlerC Sharp BackgroundWorkerC Sharp BigIntegerC Sharp Binary SerializationC Sharp BindingListC Sharp Built-in TypesC Sharp CachingC Sharp CastingC Sharp Checked and UncheckedC Sharp CLSCompliantAttributeC Sharp Code ContractsC Sharp Code Contracts and AssertionsC Sharp Collection InitializersC Sharp Comments and regionsC Sharp Common String OperationsC Sharp Conditional StatementsC Sharp Constructors and FinalizersC Sharp Creating Own MessageBox in Windows Form ApplicationC Sharp Creational Design PatternsC Sharp Cryptography (System.Security.Cryptography)C Sharp Data AnnotationC Sharp DateTime MethodsC Sharp DelegatesC Sharp Dependency InjectionC Sharp DiagnosticsC Sharp Dynamic typeC Sharp EnumC Sharp Equality OperatorC Sharp Equals and GetHashCodeC Sharp EventsC Sharp Exception HandlingC Sharp Expression TreesC Sharp Extension MethodsC Sharp File and Stream I/OC Sharp FileSystemWatcherC Sharp Func delegatesC Sharp Function with multiple return valuesC Sharp Functional ProgrammingC Sharp Garbage Collector in .NETC Sharp Generating Random NumbersC Sharp Generic Lambda Query BuilderC Sharp GenericsC Sharp Getting Started: Json with C SharpC Sharp GuidC Sharp Handling FormatException when converting string to other typesC Sharp Hash FunctionsC Sharp ICloneableC Sharp IComparableC Sharp IDisposable interfaceC Sharp IEnumerableC Sharp ILGeneratorC Sharp ImmutabilityC Sharp Implementing Decorator Design PatternC Sharp Implementing Flyweight Design PatternC Sharp Import Google ContactsC Sharp Including Font ResourcesC Sharp IndexerC Sharp InheritanceC Sharp Initializing PropertiesC Sharp INotifyPropertyChanged interfaceC Sharp InterfacesC Sharp InteroperabilityC Sharp IQueryable interfaceC Sharp IteratorsC Sharp KeywordsC Sharp Lambda expressionsC Sharp Lambda ExpressionsC Sharp LINQ QueriesC Sharp LINQ to Objects

C Sharp Lambda expressions

From WikiOD

Remarks[edit | edit source]

A lambda expression is a syntax for creating anonymous functions inline. More formally, from the C# Programming Guide:

A lambda expression is an anonymous function that you can use to create delegates or expression tree types. By using lambda expressions, you can write local functions that can be passed as arguments or returned as the value of function calls.

A lambda expression is created by using the => operator. Put any parameters on the lefthand side of the operator. On the righthand side, put an expression that can use those parameters; this expression will resolve as the return value of the function. More rarely, if necessary, a whole {code block} can be used on the righthand side. If the return type is not void, the block will contain a return statement.

Lambda Expressions as Shorthand for Delegate Initialization[edit | edit source]

public delegate int ModifyInt(int input);
ModifyInt multiplyByTwo = x => x * 2;

The above Lambda expression syntax is equivalent to the following verbose code:

public delegate int ModifyInt(int input);

ModifyInt multiplyByTwo = delegate(int x){
    return x * 2;

Lambda Expression as an Event Handler[edit | edit source]

Lambda expressions can be used to handle events, which is useful when:

  • The handler is short.
  • The handler never needs to be unsubscribed.

A good situation in which a lambda event handler might be used is given below:

smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent");

If unsubscribing a registered event handler at some future point in the code is necessary, the event handler expression should be saved to a variable, and the registration/unregistration done through that variable:

EventHandler handler = (sender, args) => Console.WriteLine("Email sent");

smtpClient.SendCompleted += handler;
smtpClient.SendCompleted -= handler;

The reason that this is done rather than simply retyping the lambda expression verbatim to unsubscribe it (-=) is that the C# compiler won't necessarily consider the two expressions equal:

EventHandler handlerA = (sender, args) => Console.WriteLine("Email sent");
EventHandler handlerB = (sender, args) => Console.WriteLine("Email sent");
Console.WriteLine(handlerA.Equals(handlerB)); // May return "False"

Note that if additional statements are added to the lambda expression, then the required surrounding curly braces may be accidentally omitted, without causing compile-time error. For example:

smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent"); emailSendButton.Enabled = true;

This will compile, but will result in adding the lambda expression (sender, args) => Console.WriteLine("Email sent"); as an event handler, and executing the statement emailSendButton.Enabled = true; immediately. To fix this, the contents of the lambda must be surrounded in curly braces. This can be avoided by using curly braces from the start, being cautious when adding additional statements to a lambda-event-handler, or surrounding the lambda in round brackets from the start:

smtpClient.SendCompleted += ((sender, args) => Console.WriteLine("Email sent"));
//Adding an extra statement will result in a compile-time error

Lambda Expressions with Multiple Parameters or No Parameters[edit | edit source]

Use parentheses around the expression to the left of the => operator to indicate multiple parameters.

delegate int ModifyInt(int input1, int input2);
ModifyInt multiplyTwoInts = (x,y) => x * y;

Similarly, an empty set of parentheses indicates that the function does not accept parameters.

delegate string ReturnString();
ReturnString getGreeting = () => "Hello world.";

Lambdas can be emitted both as `Func` and `Expression`[edit | edit source]

Assuming the following Person class:

public class Person
    public string Name { get; set; }
    public int Age { get; set; }

The following lambda:

p => p.Age > 18

Can be passed as an argument to both methods:

public void AsFunc(Func<Person, bool> func)
public void AsExpression(Expression<Func<Person, bool>> expr)

Because the compiler is capable of transforming lambdas both to delegates and Expressions.

Obviously, LINQ providers rely heavily on Expressions (exposed mainly through the IQueryable<T> interface) in order to be able to parse queries and translate them to store queries.

Put Multiple Statements in a Statement Lambda[edit | edit source]

Unlike an expression lambda, a statement lambda can contain multiple statements separated by semicolons.

delegate void ModifyInt(int input);

ModifyInt addOneAndTellMe = x =>
    int result = x + 1;

Note that the statements are enclosed in braces {}.

Remember that statement lambdas cannot be used to create expression trees.

Lambdas for both `Func` and `Action`[edit | edit source]

Typically lambdas are used for defining simple functions (generally in the context of a linq expression):

var incremented = myEnumerable.Select(x => x + 1);

Here the return is implicit.

However, it is also possible to pass actions as lambdas:

myObservable.Do(x => Console.WriteLine(x));

Passing a Lambda Expression as a Parameter to a Method[edit | edit source]

List<int> l2 = l1.FindAll(x => x > 6);

Here x => x > 6 is a lambda expression acting as a predicate that makes sure that only elements above 6 are returned.