2016-11-12 2 views
3

Voici un exemple d'utilisation covariance et contravariance pour les génériquesCovariance et contravariance dans les Interfaces

class Program 
    { 
     static void Main(string[] args) 
     { 
      ICovariant<Apple> alCov = new Covariant<Apple>(); 
      ICovariant<Fruite> fCov = alCov; 

      IContravariant<Apple> aContra = new Contravariant<Apple>(); 
      IContravariant<Apple> fContra = new Contravariant<Fruite>(); 

     } 


     public class Fruite 
     { 
      public virtual void Print() 
      { 
       Console.WriteLine("Fruite"); 
      } 
     } 

     public class Apple : Fruite 
     { 
      public override void Print() 
      { 
       Console.WriteLine("Apple"); 
      } 
     } 

     interface IContravariant<in T> 
     { 
      void Method(); 

      // This interface can be implicitly cast to MORE DERIVED (downcasting) 
      // Usually means T is used as argument 
      void Method(T argument); 
     }//interface 

     interface ICovariant<out T> 
     { 
      // This interface can be implicitly cast to LESS DERIVED (upcasting) 
      // Used for readonly collections 
      IEnumerable<T> GetList { get; } 
      // Used when T is used as return type 
      T Method(); 
     }//interface 


     public class Covariant<T> : ICovariant<T> 
     { 
      public IEnumerable<T> GetList 
      { 
       get 
       { 
        throw new NotImplementedException(); 
       } 
      } 

      public T Method() 
      { 
       throw new NotImplementedException(); 
      } 
     } 
     public class Contravariant<T> : IContravariant<T> 
     { 
      public void Method() 
      { 
       Console.Write(typeof(T)); 
      } 

      public void Method(T argument) 
      { 
       Console.Write(argument); 
      } 
     } 

    } 

Je comprends ces lignes de code, car il est similaire au polymorphisme et j'understande l'avantage derrière

ICovariant<Apple> alCov = new Covariant<Apple>(); 
ICovariant<Fruite> fCov = alCov; 

mais ce que je ne comprends pas est le bénéfice de la contravariance comme dans les lignes suivantes

IContravariant<Apple> aContra = new Contravariant<Apple>(); 
IContravariant<Apple> fContra = new Contravariant<Fruite>(); 

donc pourrait-on expliquer avec un exemple de comment puis-je en profiter.

+1

'IEqualityComparer c = new FruiteComparer(); var d = new HashSet (c); ' – PetSerAl

Répondre

1

so could anyone explain with example of how can I take the benefit of it.

Un exemple d'utilisation pourrait être la suivante:

IContravariant<Fruite> fContra = new Contravariant<Fruite>(); 
List<IContravariant<Apple>> contravariants= new List<IContravariant<Apple>>(); 
contravariants.Add(fContra); 
contravariants.Add(aContra); 

donc si vous changez IContavariant<in T> l'interface à IContavariant<T> vous obtiendrez une erreur de compilation

une bonne exemple pourrait être la méthode Distinct en Linq vous pouvez penser à une méthode qui fait es la même chose, mais ne pas utiliser IEqualityComparer<T> mais même à tous les fruits Algorithme

dans ce lien, vous pouvez trouver un exemple complet Comparing Generic Collections