Domanda

Qual è il significato dei concetti "covarianza" e "contraddizione"?

Dato 2 classi, animale e elefante (che eredita da animale ), la mia comprensione è che si otterrebbero errori di runtime se provi a mettere un Elefante in una serie di Animali, e questo accade perché l'Elefante è "più grande". (più specifico) rispetto agli animali. Ma potresti collocare un animale in una schiera di elefanti, vedendo come è garantito che l'Elefante contenga le proprietà degli animali?

È stato utile?

Soluzione

Lo hai al contrario. Puoi aggiungere un elefante a un array di animali perché è un animale ed è garantito che abbia tutti i metodi che un animale deve avere. Non è possibile aggiungere un animale a un array di elefanti perché non ha tutti i metodi richiesti da un elefante.

L'articolo di Wikipedia su covarianza e contravarianza ha una buona spiegazione di questo:

  

All'interno del sistema di tipi di un linguaggio di programmazione, un operatore da tipi a tipi è covariante se conserva l'ordinamento, =, di tipi, che ordina tipi da più specifici a più generici; è contraddittorio se inverte questo ordine. Se nessuno dei due si applica, l'operatore è invariante. Questi termini derivano dalla teoria delle categorie.

Inoltre, hai detto che il tipo Elephant era "più grande", e non è così. Il tipo di animale è "più grande" nel senso che include tipi più specifici, come Elefante, Giraffa e Leone.

Altri suggerimenti

Dai un'occhiata a questa panoramica di covarianza e contraddizione in C # 4.0 e vedi se questo aiuta:

http://blogs.msdn.com/charlie/archive/2008/10/27/linq-farm-covariance-and-contravariance-in-visual-studio-2010.aspx

Dovresti provare a leggere le pagine 45-49 di Presentazione di .NET 4.0 con Visual Studio 2010 che tratta questo esempio esatto. Ha anche delle belle foto di elefanti.

Il punto principale da eliminare è, per fare questo

var things = new List<IThing<IContent>> { new ConcreteThing() }

con:

public class ConcreteThing : IThing<ConcreteContent>
{

}

hai bisogno di " out " nella definizione dell'interfaccia, che consentirà di impostare moduli più specifici, ma qualsiasi cosa letta da IThing deve essere garantita come il tipo più generale.

public interface IThing<out T> where T : IContent
{
}

 inserisci qui la descrizione dell'immagine

public interface IGoOut<out T>
{
    T Func();
}
public interface IComeIn<in T>
{
    void Action(T obj);
}
public class GoOutClass<T>:IGoOut<T>
{
    public T Func()
    {
        return default(T);
    }
}

public class ComeInClass<T> : IComeIn<T>
{
    public void Action(T obj) {  }
}

==========================================================
object obj = null;
//Covariance Example [Array +  IEnumerable<T> +  IEnumerator<T>  +  IInterface<Out T>  +  Func<T>]
object[] array = (string[]) obj;
IEnumerable<object> enumerable = (IEnumerable<string>) obj;
IEnumerator<object> enumerator = (IEnumerator<string>)obj;
IGoOut<object> goOut = (GoOutClass<string>)obj;
Func<object> func = (Func<string>)obj;


//Contravariance Example[IInterface<in T>]
IComeIn<string> comeIn = (ComeInClass<object>) obj;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top