Perché la covarianza è proibita per la classe astratta in C #

7

Sto scavando in covarianza e controvarianza in C # e c'è una cosa che non riesco a capire. C # (AFAIK, versione 4) consente di dichiarare le interfacce e i delegati covarianti o controvarianti usando out e in parole chiave. Tuttavia, la dichiarazione della classe astratta con tali parole chiave non è possibile. Qualcuno potrebbe condividere un'idea sul perché è stato creato così? Comprendo problemi generali e problemi di covarianza e controvarianza, LSP e così via. Tuttavia, non ero in grado di farmi un'idea del perché la classe astratta non è semanticamente adatta ad essere covariante o controvariante, mentre l'interfaccia lo è.

Ecco un esempio della classe astratta solo per completezza. Non verrà compilato.

public abstract class SomeList<out T> where T : class
{

}
    
posta Vlad Stryapko 12.02.2016 - 12:06
fonte

1 risposta

2

Covarianza e controvarianza non sono consentite in nessuna classe. Poiché le classi astratte possono avere un'implementazione concreta, questo vale anche per loro. Le risposte brevi per il motivo è che (a) il CLR non lo supporta e (b) non lo supporta, perché (per covarianza):

[a class C<T>] cannot have any method that takes a T, any property of type T with a setter, or any field of type T, because fields are logically the same as property setters; T goes in [only]

e quindi la classe dovrebbe essere completamente immutabile. Allo stesso modo, una classe controvariante non può consentire un metodo che restituisce T o una proprietà di tipo T con un getter, ovvero non è possibile ricavarne i dati. Questo limita l'utilità di permetterlo (oltre il solo consentirlo nelle interfacce) in modo che non valga la pena di fare in modo che il CLR supporti questa idea.

Per favore vedi questa risposta ad un'altra domanda di Eric Lippert per maggiori dettagli (la citazione sopra è tratta da quella risposta).

    
risposta data 12.02.2016 - 14:19
fonte

Leggi altre domande sui tag