Co oznacza składnia „=>” w C #?

84

Właśnie dotarłem do tej składni w niektórych pytaniach na tym forum, ale Google i każda inna wyszukiwarka ma tendencję do blokowania w wyszukiwaniu wszystkiego oprócz liter i cyfr, więc niemożliwe jest wyszukanie "=>".

Czy ktoś może mi powiedzieć, co to jest i jak jest używane?

Wilk 5
źródło

Odpowiedzi:

86

To operator lambda.

Od C # 3 do C # 5, to było używane tylko dla wyrażeń lambda . Są to w zasadzie krótsze formy anonimowych metod wprowadzonych w C # 2, ale można je również przekształcić w drzewa wyrażeń .

Jako przykład:

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

jest równa:

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

W obu przypadkach tworzysz delegata z Personparametrem, zwracając nazwisko tej osoby (jako ciąg znaków).

W C # 6 ta sama składnia jest używana dla elementów składowych zawierających wyrażenia , np

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

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

Zobacz też:

(I rzeczywiście wiele podobnych pytań - wypróbuj tagi lambda i wyrażenia lambda ).

Jon Skeet
źródło
1
Ponieważ pytanie nie mówi nic o dokładnym przypadku, o który pytano, może rozważ zaktualizowanie tej odpowiedzi, aby zawierała również nową składnię składową składową wyrażenia?
Lasse V. Karlsen,
1
Fajnie :) Przyszedłem tutaj, ponieważ to pytanie zostało użyte jako cel do podwójnego zamknięcia, więc pomyślałem, że fajnie byłoby mieć 1 odpowiedź zamiast polować na inną w tych innych przypadkach :)
Lasse V. Karlsen
15

Jest to znacznie bardziej zwięzła forma zapisu metod. Poniższe są z grubsza równoważne:

// 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;

Wyobraź sobie wyrażenie lambda jako mówiące „daj coś, zwróć coś”. W powyższym przykładzie wyrażenie lambda x => xmówi „dane x, zwróć x”, chociaż wyrażenia lambda niekoniecznie muszą coś zwracać, w takim przypadku możesz je odczytać jako „dane x, zrób coś z x”.

Zauważ również, że istnieją trzy rzeczy zwane „delegatem”, które na początku mogą być bardzo mylące.

Metoda anonimowa używa delegatesłowa kluczowego, ale definiuje metodę bez nazwy:

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

Przypisanie metody (anonimowej, jawnej lub lambda) do odwołania powoduje utworzenie ukrytego Delegateobiektu opakowującego, który umożliwia odwołanie się do metody. (Zasadniczo rodzaj „wskaźnika funkcji zarządzanej”).

Następnie możesz również zadeklarować podpisy nazwanych metod, używając delegatesłowa kluczowego:

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

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

To deklaruje nazwany podpis, TestFuncktóry przyjmuje dwa ints i zwraca int, a następnie deklaruje odwołanie do delegata tego typu, do którego jest następnie przypisywana metoda anonimowa z pasującym podpisem.

Dave Cousineau
źródło
14

To oznacza niesamowitość. Np

x => x + 1

reprezentuje metodę, która przyjmuje x jako parametr i zwraca jego następcę.

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

przypisuje procedurę obsługi zdarzeń do przycisku, wywołując metodę, którą przechowuje MethodInfo.

Serhat Ozgel
źródło
10

oto prosty przykład z msdn

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

Wszystko przed => to parametry wejściowe, a wszystko po nim jest wyrażeniem. Możesz mieć wiele parametrów wejściowych. Lambdy są używane głównie z Linq.

Steve
źródło
8

Zamiast używać anonimowej metody takiej jak ta:

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

po prostu piszesz to tak:

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

Przyjmie typ danych na podstawie wartości zwracanej.

milot
źródło
3

=> Znacznik jest wspierany w dwóch postaciach: jako operatora lambda oraz jako separator nazwy człon i wykonania elementu w definicji ciała ekspresję.

Operator lambda

W wyrażeniach lambda operator lambda => oddziela zmienne wejściowe po lewej stronie od treści lambda po prawej stronie.

Poniższy przykład używa funkcji LINQ ze składnią metody, aby zademonstrować użycie wyrażeń lambda:

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

Definicja treści wyrażenia

Definicja treści wyrażenia ma następującą ogólną składnię:

member => expression;

gdzie wyrażenie jest prawidłowym wyrażeniem. Należy zauważyć, że wyrażenie może być wyrażeniem instrukcji tylko wtedy, gdy zwracany typ elementu członkowskiego jest void lub jeśli element członkowski jest konstruktorem, finalizatorem lub akcesorium zestawu właściwości.

Poniższy przykład przedstawia definicję treści wyrażenia dla metody Person.ToString:

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

Jest to skrócona wersja następującej definicji metody:

public override string ToString()
{
   return $"{fname} {lname}".Trim();
}
Sharon AS
źródło
4
Jeśli masz zamiar skopiować i wkleić odpowiedzi z innych witryn internetowych, dołącz przynajmniej link do źródła .
Knelis
1

Zasadniczo oznacza „wchodzi w”, jak parametr

MyObjectReference => MyObjectReference.DoSomething()

Zwykle używasz ich do przekazywania funkcji do metod jako parametrów lub w instrukcjach LINQ

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

Na przykład.

qui
źródło
0

Jest częścią składni wyrażenia lambda. Wyrażenie lambda jest zasadniczo skróconą formą delegata lub metodą anonimową. Aby to zilustrować, załóżmy, że mam tablicę ciągów pasujących do liter alfabetu. Mogłem wybrać elementy tej tablicy, które zawierały wartości większe niż „E” za pomocą następującego wyrażenia LINQ:

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

Część wyrażenia lambda po lewej stronie znaku „=>” identyfikuje nazwę zmiennej do testu (która jest przypisana do poszczególnych elementów alfabetu), a część wyrażenia lambda po prawej stronie znaku „=>” identyfikuje przetwarzanie. W tym przypadku przetwarzanie generuje wartość logiczną, której logika Where używa do określenia, czy każdy element alfabetu jest przekazywany do tablicy someLetters.

JonStonecash
źródło