Chapter84:Lambdaexpressions

No Comments

Section84.1:LambdaExpressionsasShorthandforDelegate Initialization

publicdelegateintModifyInt(intinput);

ModifyIntmultiplyByTwo=x=>x*2;

TheaboveLambdaexpressionsyntaxisequivalenttothefollowingverbosecode:

publicdelegateintModifyInt(intinput);

ModifyIntmultiplyByTwo=delegate(intx){

returnx*2;

};

Section84.2:LambdaExpressionasanEventHandler

Lambdaexpressionscanbeusedtohandleevents,whichisusefulwhen: The handler is short.

  • The handler never needs to be unsubscribed.

Agoodsituationinwhichalambdaeventhandlermightbeusedisgivenbelow:

smtpClient.SendCompleted+=(sender,args)=>Console.WriteLine(“Emailsent”);

Ifunsubscribingaregisteredeventhandleratsomefuturepointinthecodeisnecessary,theeventhandler expressionshouldbesavedtoavariable,andtheregistration/unregistrationdonethroughthatvariable:

EventHandlerhandler=(sender,args)=>Console.WriteLine(“Emailsent”);

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));//Mayreturn”False”

Notethatifadditionalstatementsareaddedtothelambdaexpression,thentherequiredsurroundingcurlybraces maybeaccidentallyomitted,withoutcausingcompile-timeerror.Forexample:

smtpClient.SendCompleted+=(sender,args)=>Console.WriteLine(“Emailsent”); emailSendButton.Enabled=true;

Thiswillcompile,butwillresultinaddingthelambdaexpression(sender,args)=>Console.WriteLine(“Emailsent”);asaneventhandler,andexecutingthestatementemailSendButton.Enabled=true;immediately.Tofix this,thecontentsofthelambdamustbesurroundedincurlybraces.Thiscanbeavoidedbyusingcurlybraces fromthestart,beingcautiouswhenaddingadditionalstatementstoalambda-event-handler,orsurroundingthe lambdainroundbracketsfromthestart:

smtpClient.SendCompleted+=((sender,args)=>Console.WriteLine(“Emailsent”));

//Addinganextrastatementwillresultinacompile-timeerror

Section84.3:LambdaExpressionswithMultipleParameters or No Parameters

Useparenthesesaroundtheexpressiontotheleftofthe=>operatortoindicatemultipleparameters.

delegateintModifyInt(intinput1,intinput2);

ModifyIntmultiplyTwoInts=(x,y)=>x*y;

Similarly,anemptysetofparenthesesindicatesthatthefunctiondoesnotaccept parameters.

delegatestringReturnString();

ReturnStringgetGreeting=()=>”Helloworld.”;

Section84.4:Lambdascanbeemittedbothas`Func`and

`Expression`

AssumingthefollowingPersonclass:

publicclassPerson

{

publicstringName{get;set; }

publicintAge{get;set;}

}

Thefollowing lambda:

p=>p.Age>18

Canbepassedasanargumenttobothmethods:

publicvoidAsFunc(Func<Person,bool>func)

publicvoidAsExpression(Expression<Func<Person,bool>>expr)

BecausethecompileriscapableoftransforminglambdasbothtodelegatesandExpressions.

Obviously,LINQprovidersrelyheavilyonExpressions(exposedmainlythroughtheIQueryable<T>interface)in ordertobeabletoparsequeriesandtranslatethemtostorequeries.

Section84.5:PutMultipleStatementsinaStatementLambda

Unlike anexpressionlambda,astatementlambda cancontainmultiplestatementsseparatedby semicolons.

delegatevoidModifyInt(intinput);

ModifyIntaddOneAndTellMe=x=>

{

intresult=x+1; Console.WriteLine(result);

};

Notethatthestatementsareenclosedinbraces{}.

Rememberthat statement lambdascannot be used tocreate expression trees.

Section 84.6: Lambdasfor both `Func`and `Action`

Typicallylambdasareusedfordefiningsimplefunctions(generallyinthecontextofalinqexpression):

varincremented=myEnumerable.Select(x=>x+1);

Herethereturnisimplicit.

However,itisalsopossibletopassactionsaslambdas:

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

Section84.7:Usinglambdasyntaxtocreateaclosure

Seeremarksfordiscussionofclosures.Supposewehaveaninterface:

publicinterfaceIMachine<TState,TInput>

{

TStateState{get;}

publicvoidInput(TInputinput);

}

andthenthefollowingisexecuted:

IMachine<int,int>machine= …;

Func<int,int>machineClosure=i=>{

machine.Input(i);

returnmachine.State;

};

NowmachineClosurereferstoafunctionfrominttoint,whichbehindthescenesusestheIMachineinstance whichmachinereferstoinordertocarryoutthecomputation.Evenifthereferencemachinegoesoutofscope,as longasthemachineClosureobjectismaintained,theoriginalIMachineinstancewillberetainedaspartofa ‘closure’,automaticallydefinedbythecompiler.

Warning: this can mean that the same function call returns different values at different times (e.g. In this example if themachinekeepsasumofitsinputs).Inlotsofcases,thismaybeunexpectedandistobeavoidedforanycodein a functional style – accidental and unexpected closures can be a source of bugs.

Section84.8:PassingaLambdaExpressionasaParameterto a Method

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

Herex=>x>6isalambdaexpressionactingasapredicatethatmakessurethatonlyelementsabove6are returned.

Section84.9:Basiclambdaexpressions

Func<int,int>add1=i=>i+1;

Func<int,int,int>add=(i,j)=>i+j;

//Behaviourallyequivalentto:

intAdd1(inti)

{

returni+1;

}

intAdd(inti,intj)

{

returni+j;

}

Console.WriteLine(add1(42));//43

Console.WriteLine(Add1(42));//43

Console.WriteLine(add(100,250));//350

Console.WriteLine(Add(100,250));//350

Section84.10:BasiclambdaexpressionswithLINQ

//assumesourceis{0,1,2,…,10}

varevens=source.Where(n=>n%2==0);

//evens={0,2,4,10}

varstrings=source.Select(n=>n.ToString());

//strings={“0″,”1”,…,“10”}

Section84.11:Lambdasyntaxwithstatementblockbody

Func<int,string>doubleThenAddElevenThenQuote=i=>{

vardoubled=2*i;

varaddedEleven=11+doubled;

return$”‘{addedEleven}'”;

};

Section 84.12: Lambda expressions with System.Linq.Expressions

Expression<Func<int,bool>>checkEvenExpression=i=>i%2==0;

//lambdaexpressionisautomaticallyconvertedtoanExpression<Func<int,bool>>

About us and this blog

We are a digital marketing company with a focus on helping our customers achieve great results across several key areas.

Request a free quote

We offer professional SEO services that help websites increase their organic search score drastically in order to compete for the highest rankings even when it comes to highly competitive keywords.

Subscribe to our newsletter!

More from our blog

See all posts
No Comments