Domanda

Non ho partecipato a PDC 2008, ma ho sentito alcune notizie che C # 4.0 è stato annunciato per supportare la covarianza e la contro-varianza generiche. In altre parole, List < string > può essere assegnato a List < object > . Come potrebbe essere?

Nel libro di Jon Skeet C # in profondità , viene spiegato perché i generici di C # non supportano la covarianza e la contro-varianza. È principalmente per la scrittura di codice sicuro. Ora, C # 4.0 è cambiato per supportarli. Porterebbe il caos?

Qualcuno sa che i dettagli su C # 4.0 possono dare qualche spiegazione?

È stato utile?

Soluzione

La varianza sarà supportata solo in modo sicuro - in effetti, usando le abilità che il CLR possiede già. Quindi gli esempi che do nel libro di come provare a usare un Elenco < Banana > come un Elenco < Fruit > (o qualunque cosa fosse) non funzioneranno ancora - ma alcuni altri scenari lo faranno.

In primo luogo, sarà supportato solo per interfacce e delegati.

In secondo luogo, richiede all'autore dell'interfaccia / delegato di decorare i parametri di tipo come in (per contravarianza) o out (per covarianza). L'esempio più ovvio è IEnumerable < T > che ti permette sempre e solo di prendere valori "quot & out" di esso - non ti consente di aggiungerne di nuovi. Questo diventerà IEnumerable < out T > . Ciò non pregiudica affatto la sicurezza dei tipi, ma ti consente di restituire un IEnumerable < string > da un metodo dichiarato per restituire IEnumerable < object > per esempio.

La contraddizione è più difficile fornire esempi concreti sull'uso delle interfacce, ma è facile con un delegato. Considera Azione < T > - che rappresenta solo un metodo che accetta un parametro T . Sarebbe bello poter convertire senza problemi usando un Action < object > come Action < string > - qualsiasi metodo che accetta un oggetto il parametro andrà bene quando viene presentato con una stringa . Naturalmente, C # 2 ha già una certa covarianza e contraddizione dei delegati, ma tramite una conversione effettiva da un tipo di delegato a un altro (creando una nuova istanza) - vedere P141-144 per esempi. C # 4 renderà questo più generico e (credo) eviterà di creare una nuova istanza per la conversione. (Sarà invece una conversione di riferimento.)

Spero che questo chiarisca un po '- per favore fatemi sapere se non ha senso!

Altri suggerimenti

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top