Bene, hai tralasciato la parte più importante che fa funzionare tutto. I parametri di tipo possono essere dedotte dai parametri degli oggetti reali passati in
Ad esempio:.
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);
}
}
}
Questa estensione metodo funziona su qualsiasi classe IEnumerable e convertirà ogni elemento nell'enumerazione un altro tipo basato sul convertitore che hai fornito. Questo è generici standard.
ora, ci sono molti modi per chiamare questo metodo:
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);
Tutti e quattro variazioni chiamano lo stesso metodo e restituiscono lo stesso risultato. L'inferenza di tipo funziona osservando i parametri passati e inferendo automaticamente i loro tipi in base a ciò che viene fornito. Nei nostri esempi sopra, è in grado di determinare che il tipo è di tipo int
perché abbiamo passato in un IEnumerable<int>
nel parametro per IEnumerable<T>
. È anche in grado di dedurre che il tipo U
è di tipo string
perché abbiamo trasmesso un Func corrispondente al tipo iniziale di T
con int
e restituendo una stringa. Quindi lo Func<T, U>
è compilato con la nostra funzione di convertitore di Func<int, string>
.
Dall'inferenza sopra, è un metodo generico standard a quel punto. Digitare i metodi di inferenza e di estensione non sono altro che convenienza/zucchero sintattico.Infatti, se decompilate l'output, potete vedere che i metodi di estensione sono sostituiti con chiamate statiche e di solito sono definiti con i parametri di tipo esplicitamente compilati. (Questo varia in base al decompilatore e alle opzioni impostate).
Posso rispondere n. 1 in modo sufficiente. Permette al metodo di lavorare con qualsiasi tipo di raccolta, piuttosto che lavorare solo per stringhe o int, o Foos o altro. Ti permette anche di confrontarti con qualsiasi tipo di valore, lascia che sia int o una stringa o una barra o [...]. Nel tuo caso specifico hai solo bisogno di selezionare un 'int' da un array di qualche tipo (che non conoscevo nemmeno come si chiamasse mind you). Usando i generici, funzionerà non solo per il tuo caso, ma per qualsiasi caso simile che abbia lo stesso problema ma con tipi diversi. Questo sarà più utile per i futuri visitatori che trovano la tua domanda. – Servy
@Servy ringraziamenti! Per i futuri lettori ho trovato anche questo post: http://stackoverflow.com/questions/4885027/how-does-generic-type-inference-work-in-c –