C# Language
Lambda-uttryck
Sök…
Anmärkningar
Ett lambda-uttryck är en syntax för att skapa anonyma funktioner inline. Mer formellt från C # Programmeringsguiden :
Ett lambda-uttryck är en anonym funktion som du kan använda för att skapa delegater eller uttrycksträdtyper. Genom att använda lambda-uttryck kan du skriva lokala funktioner som kan skickas som argument eller returneras som värdet på funktionssamtal.
Ett lambda-uttryck skapas med hjälp av operatören =>
. Lägg eventuella parametrar på vänster sida av operatören. På höger sida sätter du ett uttryck som kan använda dessa parametrar; detta uttryck kommer att lösas som funktionens returvärde. Mer sällan, om nödvändigt, kan ett helt {code block}
användas på höger sida. Om returtypen inte är ogiltig kommer blocket att innehålla ett returrätt.
Att överföra ett Lambda-uttryck som en parameter till en metod
List<int> l2 = l1.FindAll(x => x > 6);
Här är x => x > 6
ett lambda-uttryck som fungerar som ett predikat som ser till att endast element över 6 returneras.
Lambda-uttryck som kort för delegatinitialisering
public delegate int ModifyInt(int input);
ModifyInt multiplyByTwo = x => x * 2;
Ovanstående Lambda-uttryckssyntax motsvarar följande ordkod:
public delegate int ModifyInt(int input);
ModifyInt multiplyByTwo = delegate(int x){
return x * 2;
};
Lambdas för både "Func" och "Action"
Vanligtvis används lambdas för att definiera enkla funktioner (vanligtvis i samband med ett linq-uttryck):
var incremented = myEnumerable.Select(x => x + 1);
Här är return
implicit.
Det är dock också möjligt att genomföra handlingar som lambdas:
myObservable.Do(x => Console.WriteLine(x));
Lambda-uttryck med flera parametrar eller inga parametrar
Använd parenteser runt uttrycket till vänster om operatören =>
att ange flera parametrar.
delegate int ModifyInt(int input1, int input2);
ModifyInt multiplyTwoInts = (x,y) => x * y;
På liknande sätt indikerar en tom uppsättning parenteser att funktionen inte accepterar parametrar.
delegate string ReturnString();
ReturnString getGreeting = () => "Hello world.";
Lägg flera uttalanden i en uttalande Lambda
Till skillnad från ett uttryck lambda kan ett uttalande lambda innehålla flera uttalanden separerade med semikolon.
delegate void ModifyInt(int input);
ModifyInt addOneAndTellMe = x =>
{
int result = x + 1;
Console.WriteLine(result);
};
Observera att uttalandena är bifogade i hängslen {}
.
Kom ihåg att uttalande lambdas inte kan användas för att skapa uttrycksträd.
Lambdas kan släppas ut både som "Func" och "Expression"
Antagande av följande Person
:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Följande lambda:
p => p.Age > 18
Kan överföras som ett argument till båda metoderna:
public void AsFunc(Func<Person, bool> func)
public void AsExpression(Expression<Func<Person, bool>> expr)
Eftersom kompilatorn kan förändra lambdas både till delegater och Expression
.
Uppenbarligen förlitar sig LINQ-leverantörer starkt på Expression
s (exponeras främst genom IQueryable<T>
-gränssnittet) för att kunna analysera frågor och översätta dem till lagringsfrågor.
Lambda Expression som en evenemangshanterare
Lambda-uttryck kan användas för att hantera händelser, vilket är användbart när:
- Handlaren är kort.
- Handlaren behöver aldrig avskrivas.
En bra situation där en lambda-händelseshanterare kan användas ges nedan:
smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent");
Om det är nödvändigt att avregistrera en registrerad händelseshanterare vid någon framtida punkt i koden, bör händelseshanteraren uttryckas i en variabel och registreringen / avregistreringen görs genom den variabeln:
EventHandler handler = (sender, args) => Console.WriteLine("Email sent");
smtpClient.SendCompleted += handler;
smtpClient.SendCompleted -= handler;
Anledningen till att detta görs snarare än att helt enkelt skriva in lambda-uttrycket ordentligt för att avsluta prenumerationen ( -=
) är att C # -kompilatorn inte nödvändigtvis anser att de två uttrycka är lika:
EventHandler handlerA = (sender, args) => Console.WriteLine("Email sent");
EventHandler handlerB = (sender, args) => Console.WriteLine("Email sent");
Console.WriteLine(handlerA.Equals(handlerB)); // May return "False"
Observera att om ytterligare uttalanden läggs till i lambda-uttrycket, kan de omgivande lockiga hängslen av misstag utelämnas utan att orsaka kompileringstidsfel. Till exempel:
smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent"); emailSendButton.Enabled = true;
Detta kommer att sammanställas, men kommer att lägga till lambda-uttrycket (sender, args) => Console.WriteLine("Email sent");
som en händelsehanterare och exekverar uttalandet emailSendButton.Enabled = true;
omedelbart. För att fixa detta måste innehållet i lambdaen omges i lockiga hängslen. Detta kan undvikas genom att använda lockiga hängslen från början, vara försiktiga när du lägger till ytterligare uttalanden till en lambda-händelseshanterare eller omger lambda i runda konsoler från början:
smtpClient.SendCompleted += ((sender, args) => Console.WriteLine("Email sent"));
//Adding an extra statement will result in a compile-time error