Was bedeutet die Syntax '=>' in C #?

81

Ich bin gerade in einigen Fragen in diesem Forum auf diese Syntax gestoßen, aber Google und jede andere Suchmaschine neigen dazu, alles andere als Buchstaben und Zahlen bei der Suche auszublenden, sodass es unmöglich ist, "=>" zu suchen.

Kann mir jemand sagen, was es ist und wie es verwendet wird?

Wolf5
quelle

Antworten:

84

Es ist der Lambda-Operator.

Von C # 3 bis C # 5 wurde dies nur für Lambda-Ausdrücke verwendet . Dies ist im Grunde eine kürzere Form der in C # 2 eingeführten anonymen Methoden , kann aber auch in Ausdrucksbäume konvertiert werden .

Als Beispiel:

Func<Person, string> nameProjection = p => p.Name;

ist äquivalent zu:

Func<Person, string> nameProjection = delegate (Person p) { return p.Name; };

In beiden Fällen erstellen Sie einen Delegaten mit einem PersonParameter und geben den Namen dieser Person (als Zeichenfolge) zurück.

In C # 6 wird dieselbe Syntax für Mitglieder mit Ausdruckskörper verwendet , z

// Expression-bodied property
public int IsValid => name != null && id != -1;

// Expression-bodied method
public int GetHashCode() => id.GetHashCode();

Siehe auch:

(Und in der Tat viele ähnliche Fragen - probieren Sie die Tags Lambda und Lambda-Ausdrücke aus .)

Jon Skeet
quelle
1
Da die Frage nichts über den genauen Fall aussagt, über den gefragt wird, sollten Sie diese Antwort möglicherweise so aktualisieren, dass sie auch die Syntax des neuen Ausdrucks enthält.
Lasse V. Karlsen
1
Schön :) Ich bin gerade hierher gekommen, weil diese Frage als Ziel für das doppelte Schließen verwendet wurde. Ich dachte, es wäre schön, eine Antwort zu haben, anstatt in diesen anderen Fällen nach einer anderen zu suchen :)
Lasse V. Karlsen
14

Es bedeutet Großartigkeit. Zum Beispiel

x => x + 1

stellt eine Methode dar, die x als Parameter verwendet und dessen Nachfolger zurückgibt.

button.Click += new EventHandler((sender, e) => methodInfo.Invoke(null, new object[] { sender, e }));

Weist einer Schaltfläche einen Ereignishandler zu, indem eine Methode aufgerufen wird, die eine MethodInfo enthält.

Serhat Ozgel
quelle
14

Es ist eine viel präzisere Form der Methodennotation. Folgendes ist ungefähr gleichwertig:

// explicit method
int MyFunc(int pParam) {
   return pParam;
}

// anonymous (name-less) method
// note that the method is "wrapped" up in a hidden object (Delegate) this way
// so there is a very tiny bit of overhead compared to an explicit method
// (though it's really the assignment that causes that and would also happen
// if you assigned an explicit method to a reference)
Func<int, int> MyFunc = delegate (int pParam) { return pParam; };

// lambda expression (also anonymous)
// basically identical to anonymous method,
// except with everything inferred as much as possible, intended to be minimally verbose
Func<int, int> MyFunc = x => x;

// and => is now also used for "expression-bodied" methods
// which let you omit the return keyword and braces if you can evaluate
// to something in one line
int MyFunc(int pParam) =>
   pParam;

Stellen Sie sich einen Lambda-Ausdruck vor, der sagt: "Etwas gegeben, etwas zurückgeben". Im obigen Beispiel x => xsagt der Lambda-Ausdruck "gegebenes x, gib x zurück", obwohl Lambda-Ausdrücke nicht unbedingt etwas zurückgeben müssen. In diesem Fall könnten Sie sie als "gegebenes x, mach etwas mit x" lesen.

Beachten Sie auch, dass es drei Dinge gibt, die als "Delegierter" bezeichnet werden und zunächst sehr verwirrend sein können.

Eine anonyme Methode verwendet das delegateSchlüsselwort, definiert jedoch eine Methode ohne Namen:

Func<int, int> = delegate (int x) { return x; };

Durch das Zuweisen einer Methode (anonym, explizit oder Lambda) zu einer Referenz wird ein verstecktes DelegateWrapper-Objekt erstellt, mit dem auf die Methode verwiesen werden kann. (Grundsätzlich eine Art "verwalteter Funktionszeiger".)

Und dann können Sie auch erklären benannte Methode Signaturen die Verwendung von delegateSchlüsselwort auch:

public delegate int TestFunc(int x, int y);

TestFunc myFunc = delegate (int x, int y) { return x + y; };

Dies deklariert eine benannte Signatur TestFunc, die zwei intSekunden benötigt und eine zurückgibt int, und deklariert dann eine Delegatenreferenz dieses Typs, der dann eine anonyme Methode mit übereinstimmender Signatur zugewiesen wird.

Dave Cousineau
quelle
10

Hier ist ein einfaches Beispiel aus msdn

delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25

Alles vor dem => sind die Eingabeparameter, und alles danach ist der Ausdruck. Sie können mehrere Eingabeparameter haben. Lambdas werden hauptsächlich mit Linq verwendet.

Steve
quelle
8

Anstatt eine anonyme Methode wie diese zu verwenden:

somevar.Find(delegate(int n)
{
   if(n < 10)
      return n;
});

du schreibst es einfach so:

somevar.Find(n => n < 10);

Der Datentyp wird basierend auf dem Rückgabewert verwendet.

Milot
quelle
3

Das Token => wird in zwei Formen unterstützt: als Lambda-Operator und als Trennzeichen eines Mitgliedsnamens sowie als Mitgliedsimplementierung in einer Ausdruckskörperdefinition.

Lambda-Betreiber

In Lambda-Ausdrücken trennt der Lambda-Operator => die Eingangsvariablen auf der linken Seite vom Lambda-Körper auf der rechten Seite.

Im folgenden Beispiel wird die LINQ-Funktion mit Methodensyntax verwendet, um die Verwendung von Lambda-Ausdrücken zu demonstrieren:

string[] words = { "bot", "apple", "apricot" };
int minimalLength = words
  .Where(w => w.StartsWith("a"))
  .Min(w => w.Length);
Console.WriteLine(minimalLength);   // output: 5

Definition des Ausdruckskörpers

Eine Ausdruckskörperdefinition hat die folgende allgemeine Syntax:

member => expression;

Dabei ist Ausdruck ein gültiger Ausdruck. Beachten Sie, dass Ausdruck nur dann ein Anweisungsausdruck sein kann, wenn der Rückgabetyp des Mitglieds ungültig ist oder wenn das Mitglied ein Konstruktor, ein Finalizer oder ein Eigenschaftssatz-Accessor ist.

Das folgende Beispiel zeigt eine Ausdruckskörperdefinition für eine Person.ToString-Methode:

public override string ToString() => $"{fname} {lname}".Trim();

Es ist eine Kurzversion der folgenden Methodendefinition:

public override string ToString()
{
   return $"{fname} {lname}".Trim();
}
Sharon AS
quelle
4
Wenn Sie Antworten von anderen Websites kopieren und einfügen möchten, fügen Sie mindestens einen Link zur Quelle hinzu .
Knelis
1

Es bedeutet im Grunde "geht in", wie ein Parameter

MyObjectReference => MyObjectReference.DoSomething()

Normalerweise verwenden Sie sie, um Funktionen als Parameter oder in LINQ-Anweisungen an Methoden zu übergeben

MyCollection.Where(myobj => myobj.Age>10)

Zum Beispiel.

qui
quelle
0

Es ist Teil der Syntax eines Lambda-Ausdrucks. Ein Lambda-Ausdruck ist im Wesentlichen eine Kurzform eines Delegaten oder einer anonymen Methode. Nehmen wir zur Veranschaulichung an, dass ich eine Reihe von Zeichenfolgen habe, die mit den Buchstaben des Alphabets übereinstimmen. Ich könnte die Mitglieder dieses Arrays, die Werte größer als "E" enthielten, mit dem folgenden LINQ-Ausdruck auswählen:

var someLetters = alphabet.Where (l => l> "E");

Der Teil des Lambda-Ausdrucks links vom "=>" identifiziert den Variablennamen für den Test (der auf die einzelnen Elemente des Alphabets festgelegt ist) und der Teil des Lambda-Ausdrucks rechts vom "=>" identifiziert das Verarbeiten. In diesem Fall erzeugt die Verarbeitung einen booleschen Wert, anhand dessen die Where-Logik bestimmt, ob jedes Mitglied des Alphabets an das someLetters-Array übergeben wird.

JonStonecash
quelle