2017-06-08 65 views
6

Znalazłem mały skrypt, który rozumiem w pełni. Mam ciąg znaków z "1 -2 5 40" na przykład. Odczytuje ciąg wejściowy, dzieli go na tablicę tymczasową. Następnie ta tablica jest analizowana i każdy element jest przekształcany w liczbę całkowitą. Cała sprawa polega na tym, by podać najbliższą liczbę całkowitą do zera.C# notation understanding Select (int.Parse)

Ale nie rozumiem, że jest notacja Wybierz (int.Parse). Nie ma tu wyrażenia lambda, a metoda int.Parse nie jest wywoływana w nawiasach. To samo z OrderBy (Math.Abs)

góry dziękuję =)

var temps = Console.ReadLine().Split(new []{' '}, StringSplitOptions.RemoveEmptyEntries); 

var result = temps.Select(int.Parse) 
.OrderBy(Math.Abs) 
.ThenByDescending(x => x) 
.FirstOrDefault(); 

Odpowiedz

11

int.Parse to grupa metoda - co widzisz jest konwersja grupa metoda delegata. Aby go zobaczyć bez LINQ:

Func<string, int> parser = int.Parse; 
int x = parser("10"); // x=10 

To głównie równoważne:

Func<string, int> parser = text => int.Parse(text); 

... chociaż istnieje wiele różnic, jeśli chcesz, aby przejść do szczegółów :)

0

int. Parse jest metodą z łańcuchem znaków podpisu -> int (lub faktycznie grupą metod, z różnymi sygnaturami, ale kompilator może wywnioskować, że potrzebujesz tego, ponieważ jest to jedyny, który pasuje do:

Ty może użyć tej metody jako parametru wszędzie tam, gdzie można podać parametr delegata z tym samym podpisem.

+0

To nie wyjaśnia, dlaczego można go używać w ten sposób. –

5

jest prawie równoważny z Select(x => int.Parse(x)).

Wymaga wymagającej Func<T, R>, która w tym przypadku jest również sygnaturą int.Parse (ma pojedynczy parametr z wartością zwracaną). Przeprowadza konwersję grupy metod do odpowiedniego uczestnika.

W tym przypadku Func<T, R> zostanie zamapowany na Func<string, int>, więc pasuje do podpisu int Parse(string).

0

Parametrem .Select() jest Func<T1, T2>() gdzie T1 to parametr wejściowy (poszczególne wartości temps) i T2 jest typ wrócimy.

Zwykle jest to zapisywane jako funkcja lambda: x => return x + 1 itd. Jednak można zastosować dowolną metodę zgodną z definicjami ogólnymi bez konieczności zapisywania jej jako lambda, ponieważ nazwa metody jest taka sama jak przypisanie wartości lambda do zmienna.

Tak więc Func<string, int> parseInt = s => Convert.ToInt32(s); jest syntaktycznie równoważne wywołaniu metody int.Parse(s).

Język tworzy skrót automatycznego przekazywania parametru Func do metody wewnętrznej, aby utworzyć bardziej czytelny kod.

0

Wybierz LINQ IEnumerable <> Rozszerzenie metoda podpis wygląda tak:

public static IEnumerable<TResult> Select<TSource, TResult>(
    this IEnumerable<TSource> source, 
    Func<TSource, TResult> selector 
) 

Spójrz na selector argument. W twoim przypadku można przejść do wybranego .Net standardową funkcję int.Parse która ma podpis:

public static int Parse(
    string s 
) 

.Net kompilator może konwertować delegatów Func < ...> lub działania < ...>. W przypadku int.Parse można go przekonwertować na Func i dlatego można go przekazać jako argument do metody Select.

Dokładnie to samo z OrderBy. Popatrz też na jego podpis.