C# Language
Lambda-Ausdrücke
Suche…
Bemerkungen
Ein Lambda-Ausdruck ist eine Syntax zum Erstellen anonymer Funktionen inline. Formaler aus dem C # -Programmierhandbuch :
Ein Lambda-Ausdruck ist eine anonyme Funktion, die Sie zum Erstellen von Delegaten oder Ausdrucksbaumtypen verwenden können. Mithilfe von Lambda-Ausdrücken können Sie lokale Funktionen schreiben, die als Argumente übergeben oder als Wert von Funktionsaufrufen zurückgegeben werden können.
Ein Lambda-Ausdruck wird mit dem Operator =>
. Setzen Sie die Parameter auf der linken Seite des Operators. Fügen Sie auf der rechten Seite einen Ausdruck ein, der diese Parameter verwenden kann. Dieser Ausdruck wird als Rückgabewert der Funktion aufgelöst. Seltener kann bei Bedarf ein ganzer {code block}
auf der rechten Seite verwendet werden. Wenn der Rückgabetyp nicht ungültig ist, enthält der Block eine Rückgabeanweisung.
Übergeben eines Lambda-Ausdrucks als Parameter an eine Methode
List<int> l2 = l1.FindAll(x => x > 6);
Hier ist x => x > 6
ein Lambda-Ausdruck, der als Prädikat fungiert und dafür sorgt, dass nur Elemente über 6 zurückgegeben werden.
Lambda-Ausdrücke als Abkürzung für die Initialisierung von Delegaten
public delegate int ModifyInt(int input);
ModifyInt multiplyByTwo = x => x * 2;
Die obige Lambda-Ausdruckssyntax entspricht dem folgenden ausführlichen Code:
public delegate int ModifyInt(int input);
ModifyInt multiplyByTwo = delegate(int x){
return x * 2;
};
Lambdas sowohl für "Func" als auch für "Action"
Typischerweise werden Lambdas zur Definition einfacher Funktionen verwendet (im Allgemeinen im Kontext eines linq-Ausdrucks)
var incremented = myEnumerable.Select(x => x + 1);
Hier ist die return
implizit.
Es ist jedoch auch möglich, Aktionen als Lambdas zu übergeben:
myObservable.Do(x => Console.WriteLine(x));
Lambda-Ausdrücke mit mehreren Parametern oder ohne Parameter
Verwenden Sie in Klammern den Ausdruck links vom Operator =>
, um mehrere Parameter anzugeben.
delegate int ModifyInt(int input1, int input2);
ModifyInt multiplyTwoInts = (x,y) => x * y;
In ähnlicher Weise zeigt ein leerer Satz von Klammern an, dass die Funktion keine Parameter akzeptiert.
delegate string ReturnString();
ReturnString getGreeting = () => "Hello world.";
Mehrere Anweisungen in eine Anweisung einfügen Lambda
Im Gegensatz zu einem Ausdruck Lambda kann ein Anweisungs-Lambda mehrere durch Semikola getrennte Anweisungen enthalten.
delegate void ModifyInt(int input);
ModifyInt addOneAndTellMe = x =>
{
int result = x + 1;
Console.WriteLine(result);
};
Beachten Sie, dass die Anweisungen in geschweiften Klammern {}
.
Beachten Sie, dass Anweisungslambas nicht zum Erstellen von Ausdrucksbäumen verwendet werden können.
Lambdas können sowohl als "Func" als auch als "Expression" ausgegeben werden
Angenommen, die folgende Person
:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Das folgende Lambda:
p => p.Age > 18
Kann als Argument an beide Methoden übergeben werden:
public void AsFunc(Func<Person, bool> func)
public void AsExpression(Expression<Func<Person, bool>> expr)
Weil der Compiler Lambdas sowohl in Delegierte als auch in Expression
s umwandeln kann.
Offensichtlich verlassen sich LINQ-Provider stark auf Expression
s (hauptsächlich über die IQueryable<T>
-Schnittstelle), um Abfragen analysieren und in Abfragen speichern zu können.
Lambda-Ausdruck als Ereignishandler
Mit Lambda-Ausdrücken können Ereignisse behandelt werden. Dies ist nützlich, wenn:
- Der Handler ist kurz.
- Der Handler muss niemals abgemeldet werden.
Eine gute Situation, in der ein Lambda-Event-Handler verwendet werden kann, ist unten angegeben:
smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent");
Wenn das Abbestellen eines registrierten Ereignishandlers zu einem späteren Zeitpunkt im Code erforderlich ist, muss der Ausdruck des Ereignishandlers in einer Variablen gespeichert werden, und die Registrierung / Aufhebung der Registrierung erfolgt über diese Variable:
EventHandler handler = (sender, args) => Console.WriteLine("Email sent");
smtpClient.SendCompleted += handler;
smtpClient.SendCompleted -= handler;
Der Grund dafür ist, dass Sie den Lambda-Ausdruck nicht einfach wörtlich erneut eingeben ( -=
), weil der C # -Compiler die beiden Ausdrücke nicht unbedingt als gleich betrachtet:
EventHandler handlerA = (sender, args) => Console.WriteLine("Email sent");
EventHandler handlerB = (sender, args) => Console.WriteLine("Email sent");
Console.WriteLine(handlerA.Equals(handlerB)); // May return "False"
Wenn dem Lambda-Ausdruck zusätzliche Anweisungen hinzugefügt werden, können versehentlich die erforderlichen umgebenden geschweiften Klammern weggelassen werden, ohne einen Kompilierungsfehler zu verursachen. Zum Beispiel:
smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent"); emailSendButton.Enabled = true;
Dies wird kompiliert, führt jedoch zum Hinzufügen des Lambda-Ausdrucks (sender, args) => Console.WriteLine("Email sent");
als Event-Handler und Ausführen der Anweisung emailSendButton.Enabled = true;
sofort. Um dies zu beheben, muss der Inhalt des Lambda von geschweiften Klammern umgeben sein. Dies kann vermieden werden, indem von Anfang an geschweifte Klammern verwendet werden, wenn Sie zusätzliche Anweisungen zu einem Lambda-Event-Handler hinzufügen oder das Lambda von Anfang an in runde Klammern einschließen:
smtpClient.SendCompleted += ((sender, args) => Console.WriteLine("Email sent"));
//Adding an extra statement will result in a compile-time error