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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow