Question

Que signifient les concepts de "covariance" et de "contravariance"?

Sur 2 classes, Animal et Éléphant (qui hérite de Animal ), je pense que vous obtiendrez des erreurs d'exécution. si vous essayez de placer un éléphant dans une rangée d’Animaux, et cela se produit parce que l’éléphant est "plus gros" (plus spécifique) que Animal. Mais pourriez-vous placer un animal dans un tableau d’éléphants, en voyant comment il est garanti qu’il contient les propriétés de cet animal?

Était-ce utile?

La solution

Vous l'avez à l'envers. Vous pouvez ajouter un éléphant à un tableau d’animaux parce qu’il est un animal et que toutes les méthodes qu’un animal doit posséder sont garanties. Vous ne pouvez pas ajouter un animal à un tableau Elephant car il ne dispose pas de toutes les méthodes qu'un éléphant doit posséder.

L'article de Wikipedia sur covariance et contravariance a une bonne explication de cela:

  

Dans le système de types d'un langage de programmation, un opérateur de types en types est covariant s'il préserve l'ordre, =, de types, qui classe les types de types plus spécifiques à des types plus génériques; il est contravariant s'il inverse cet ordre. Si aucune de celles-ci ne s'applique, l'opérateur est invariant. Ces termes proviennent de la théorie des catégories.

De plus, vous avez dit que le type Elephant était "plus gros" et ce n’est pas le cas. Le type Animal est " plus gros " dans le sens où il inclut des types plus spécifiques, tels que Elephant, Giraffe et Lion.

Autres conseils

Consultez cet aperçu de la covariance et de la contravariance en C # 4.0 et voyez si cela vous aide:

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

Vous devriez essayer de lire les pages 45 à 49 de Présentation de .NET 4.0 avec Visual Studio 2010 qui traite de cet exemple exact. On y trouve même de belles photos d’éléphants.

Le point principal à prendre est de faire ceci

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

avec:

public class ConcreteThing : IThing<ConcreteContent>
{

}

vous avez besoin du " out " dans la définition de l’interface, ce qui permettra de définir des formulaires plus spécifiques, mais il faut garantir que tout ce qui est lu dans IThing soit du type plus général.

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

 entrer la description de l'image ici

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;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top