Szukaj…


Uwagi

Wyrażenie lambda to składnia do tworzenia wbudowanych anonimowych funkcji. Bardziej formalnie, z Przewodnika programowania w języku C # :

Wyrażenie lambda to anonimowa funkcja, której można użyć do tworzenia delegatów lub typów drzew wyrażeń. Korzystając z wyrażeń lambda, możesz pisać funkcje lokalne, które mogą być przekazywane jako argumenty lub zwracane jako wartość wywołań funkcji.

Wyrażenie lambda jest tworzone za pomocą operatora => . Umieść dowolne parametry po lewej stronie operatora. Po prawej stronie umieść wyrażenie, które może korzystać z tych parametrów; to wyrażenie zostanie rozpoznane jako wartość zwracana przez funkcję. Rzadziej, jeśli to konieczne, po prawej stronie można użyć całego {code block} . Jeśli typ zwracany nie jest nieważny, blok będzie zawierał instrukcję return.

Przekazywanie wyrażenia lambda jako parametru do metody

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

Tutaj x => x > 6 jest wyrażeniem lambda działającym jako predykat, który zapewnia, że zwracane są tylko elementy powyżej 6.

Wyrażenia lambda jako skrót dla inicjowania delegatów

public delegate int ModifyInt(int input);
ModifyInt multiplyByTwo = x => x * 2;

Powyższa składnia wyrażenia Lambda jest równoważna z następującym pełnym kodem:

public delegate int ModifyInt(int input);

ModifyInt multiplyByTwo = delegate(int x){
    return x * 2;
};

Lambdas zarówno dla „Func”, jak i „Action”

Zazwyczaj lambda są używane do definiowania prostych funkcji (ogólnie w kontekście wyrażenia linq):

var incremented = myEnumerable.Select(x => x + 1);

Tutaj return jest niejawny.

Możliwe jest również przekazywanie akcji jako lambdas:

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

Wyrażenia lambda z wieloma parametrami lub bez parametrów

Użyj nawiasów wokół wyrażenia po lewej stronie operatora => , aby wskazać wiele parametrów.

delegate int ModifyInt(int input1, int input2);
ModifyInt multiplyTwoInts = (x,y) => x * y;

Podobnie pusty zestaw nawiasów oznacza, że funkcja nie akceptuje parametrów.

delegate string ReturnString();
ReturnString getGreeting = () => "Hello world.";

Umieść wiele instrukcji w instrukcji Lambda

W przeciwieństwie do wyrażenia lambda, instrukcja lambda może zawierać wiele instrukcji oddzielonych średnikami.

delegate void ModifyInt(int input);

ModifyInt addOneAndTellMe = x =>
{
    int result = x + 1;
    Console.WriteLine(result);
};

Zauważ, że instrukcje są ujęte w nawiasy klamrowe {} .

Pamiętaj, że wyrażenia lambdas nie można używać do tworzenia drzew wyrażeń.

Lambda może być emitowana zarówno jako „Func”, jak i „Expression”

Zakładając następującą klasę Person :

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Następująca lambda:

p => p.Age > 18

Można przekazać jako argument do obu metod:

public void AsFunc(Func<Person, bool> func)
public void AsExpression(Expression<Func<Person, bool>> expr)

Ponieważ kompilator jest w stanie transformować lambdy zarówno do delegatów, jak i Expression .

Oczywiście dostawcy LINQ w dużej mierze polegają na Expression (udostępnionych głównie przez interfejs IQueryable<T> ), aby móc parsować zapytania i tłumaczyć je do przechowywania zapytań.

Wyrażenie lambda jako moduł obsługi zdarzeń

Wyrażeń lambda można używać do obsługi zdarzeń, co jest przydatne, gdy:

  • Przewodnik jest niski.
  • Przewodnik nigdy nie musi być wypisany z subskrypcji.

Dobra sytuacja, w której można zastosować moduł obsługi zdarzeń lambda, podano poniżej:

smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent");

Jeśli konieczne jest anulowanie subskrypcji zarejestrowanej procedury obsługi zdarzeń w pewnym przyszłym punkcie kodu, wyrażenie procedury obsługi zdarzeń powinno zostać zapisane w zmiennej, a rejestracja / wyrejestrowanie należy wykonać za pomocą tej zmiennej:

EventHandler handler = (sender, args) => Console.WriteLine("Email sent");

smtpClient.SendCompleted += handler;
smtpClient.SendCompleted -= handler;

Powodem, dla którego jest to wykonywane, a nie po prostu przepisywanie wyrażenia lambda dosłownie w celu wypisania go ( -= ), jest to, że kompilator C # niekoniecznie uznaje oba wyrażenia za równe:

EventHandler handlerA = (sender, args) => Console.WriteLine("Email sent");
EventHandler handlerB = (sender, args) => Console.WriteLine("Email sent");
Console.WriteLine(handlerA.Equals(handlerB)); // May return "False"

Należy zauważyć, że jeśli do wyrażenia lambda zostaną dodane dodatkowe instrukcje, wówczas wymagane otaczające nawiasy klamrowe można przypadkowo pominąć, nie powodując błędu czasu kompilacji. Na przykład:

smtpClient.SendCompleted += (sender, args) => Console.WriteLine("Email sent"); emailSendButton.Enabled = true;

Spowoduje to kompilację, ale spowoduje dodanie wyrażenia lambda (sender, args) => Console.WriteLine("Email sent"); jako emailSendButton.Enabled = true; obsługi zdarzeń i wykonywanie instrukcji emailSendButton.Enabled = true; natychmiast. Aby to naprawić, zawartość lambda musi być otoczona nawiasami klamrowymi. Można tego uniknąć, używając od początku nawiasów klamrowych, zachowując ostrożność podczas dodawania dodatkowych instrukcji do modułu obsługi zdarzeń lambda lub otaczając lambda w nawiasach okrągłych od początku:

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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow