Pominąłem najważniejszą część, która sprawia, że wszystko działa. Parametry typu może wnioskować o rzeczywistych parametrów obiektów przekazanych w
Na przykład:.
static class Extensions {
internal static IEnumerable<U> Test<T, U>(
this IEnumerable<T> items,
Func<T, U> converter) {
foreach (T item in items) {
yield return converter(item);
}
}
}
To rozszerzenie metoda działa na dowolnym IEnumerable klasy i zamieni każdy element wyliczenia do innego typu w oparciu na podanym konwerterze. To są standardowe leki generyczne.
Teraz, istnieje wiele sposobów, aby wywołać tę metodę:
IEnumerable<int> values = Enumerable.Range<int>(1, 10);
Func<int, string> converter = i => i.ToString("0.00");
// Variation 1, explicit calling
IEnumerable<string> results1 = Extensions.Test<int, string>(values, converter);
// Variation 2, explicit calling with type inference
IEnumerable<string> results2 = Extensions.Test(values, converter);
// Variation 3, extension method calling, still providing explicit types
IEnumerable<string> results3 = values.Test<int, string>(converter);
// Variation 4, extension method with type inference
IEnumerable<string> results4 = values.Test(converter);
Wszystkie cztery odmiany nazywają tę samą metodę i zwraca ten sam wynik. Inferencja typów działa, patrząc na parametry przekazane i automatycznie wnioskuje ich typy na podstawie dostarczanych informacji. W naszych przykładach powyżej można stwierdzić, że typ T
jest typu int
, ponieważ przekazaliśmy parametr IEnumerable<int>
do parametru IEnumerable<T>
. Jest również w stanie wywnioskować, że typ U
jest typu string
, ponieważ przeszliśmy w Func pasującym do początkowego typu T
z int
i zwracając ciąg znaków. Tak więc Func<T, U>
jest wypełniony naszą funkcją konwertera Func<int, string>
.
Z powyższego wywodu jest to standardowa metoda standardowa w tym punkcie. Metody wnioskowania i rozszerzenia są niczym więcej niż wygodą/cukrem syntaktycznym.W rzeczywistości, jeśli dekompilujesz dane wyjściowe, możesz zauważyć, że metody rozszerzeń są zastępowane przez wywołania statyczne i są zwykle definiowane z jawnie wypełnionymi parametrami typu. (To zależy od twojego dekompilatora i ustawionych opcji).
Mogę odpowiedzieć na pytanie nr 1 po prostu. Pozwala to na pracę z dowolnym typem kolekcji, a nie tylko na łańcuchach lub intach, Foos czy cokolwiek innego. Pozwala także na porównanie z dowolnym typem wartości, niech to będzie int lub string lub pasek lub [...]. W twoim konkretnym przypadku wystarczy wybrać 'int' z tablicy jakiegoś typu (że nawet nie znałem nazwy umysłu). Używając generyków, będzie działać nie tylko w twoim przypadku, ale w każdym podobnym przypadku, który ma ten sam problem, ale z różnymi typami. Będzie to bardziej pomocne dla przyszłych użytkowników, którzy znajdą Twoje pytanie. – Servy
@Servy dzięki! Dla przyszłych czytelników znalazłem również ten post: http://stackoverflow.com/questions/4885027/how-does-generic-type-inference-work-in-c- –