Getting started with C# LanguageVerbatim StringsOperatorsExtension MethodsCollection InitializersString InterpolationC# 6.0 FeaturesConstructors and FinalizersKeywordsGenericsReflectionInheritanceNull-Coalescing OperatorUsing StatementString Escape SequencesException HandlingNull-conditional OperatorsBuilt-in TypesLambda expressionsAsync-AwaitPropertiesThreadingUsing DirectiveMethodsYield KeywordEventsLINQ QueriesCommon String OperationsExpression TreesOverload ResolutionString.Formatnameof OperatorUnsafe Code in .NETInitializing PropertiesBindingList<T>ILGeneratorObject initializersXML Documentation CommentsPreprocessor directivesDynamic typeAnonymous typesStructsTuplesEnumAccess ModifiersTask Parallel LibraryAttributesGuidSingleton ImplementationDelegatesNullable typesGarbage Collector in .NetNetworkingArraysEquality OperatorLock StatementAction FiltersXmlDocument and the System.Xml namespaceDateTime MethodsBackgroundWorkerPolymorphismStatic ClassesIndexerIDisposable interfaceAliases of built-in typesImmutabilityXDocument and the System.Xml.Linq namespaceC# 7.0 FeaturesPerforming HTTP requestsGenerating Random Numbers in C#LoopingNamed ArgumentsDiagnosticsInterfacesIEnumerableNaming ConventionsAn overview of c# collectionsChecked and UncheckedRecursionFunctional ProgrammingLiteralsCastingNullReferenceExceptionFunc delegatesLINQ to XMLHash FunctionsHandling FormatException when converting string to other typesCryptography (System.Security.Cryptography)INotifyPropertyChanged interfaceValue type vs Reference typeC# 4.0 FeaturesIQueryable interfaceTask Parallel Library (TPL) Dataflow ConstructsStreamRuntime CompileConditional StatementsInteroperabilityOverflowEquals and GetHashCodeType ConversionParallel LINQ (PLINQ)String ManipulationString ConcatenatePartial class and methodsStopwatchesRegex ParsingC# ScriptC# 3.0 FeaturesAsync/await, Backgroundworker, Task and Thread ExamplesTimersFunction with multiple return valuesBinary SerializationMaking a variable thread safeIComparableCode ContractsIteratorsAssemblyInfo.cs ExamplesFile and Stream I/OCode Contracts and AssertionsCachingC# 5.0 FeaturesImplementing Flyweight Design PatternStringBuilderImplementing Decorator Design PatternAccessing DatabasesT4 Code GenerationMicrosoft.Exchange.WebServices.NET Compiler Platform (Roslyn)Data AnnotationUsing SQLite in C#System.Management.AutomationFileSystemWatcherSystem.DirectoryServices.Protocols.LdapConnectionNamed and Optional ArgumentsComments and regionsC# Authentication handlerPointers & Unsafe CodePointersHow to use C# Structs to create a Union type (Similar to C Unions)BigIntegerDependency InjectionReactive Extensions (Rx)Creational Design PatternsCreating a Console Application using a Plain-Text Editor and the C# Compiler (csc.exe)Reading and writing .zip filesGeneric Lambda Query BuilderImport Google ContactsLambda ExpressionsCLSCompliantAttributeObservableCollection<T>Synchronization Context in Async-AwaitICloneableRead & Understand StacktracesLinq to ObjectsASP.NET IdentityAccess network shared folder with username and passwordAsynchronous SocketStructural Design PatternsO(n) Algorithm for circular rotation of an arrayCreating Own MessageBox in Windows Form ApplicationIncluding Font ResourcesObject Oriented Programming In C#Using json.netGetting Started: Json with C#Windows Communication Foundation

Lambda expressions

Other topics

Remarks:

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.

Passing a Lambda Expression as a Parameter to a Method

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.

Lambda Expressions as Shorthand for Delegate Initialization

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;
};

Lambdas for both `Func` and `Action`

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));

Lambda Expressions with Multiple Parameters or No Parameters

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.";

Put Multiple Statements in a Statement Lambda

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;
    Console.WriteLine(result);
};

Note that the statements are enclosed in braces {}.

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

Lambdas can be emitted both as `Func` and `Expression`

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.

Lambda Expression as an Event Handler

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

Contributors

Topic Id: 46

Example Ids: 196,215,278,280,281,2551,4560

This site is not affiliated with any of the contributors.