Example analysis of c Covariant and contravariant

  • 2020-11-18 06:26:18
  • OfStack

The principle and application of c# covariant and contravariant are introduced. Share to everybody for everybody reference. The details are as follows:

The transition from subclass to superclass is covariant, identified by out keyword, and the transition from superclass to subclass is contravariant, using in keyword

Covariant and contravariant applications

1. Covariant array

Animal[] animalArray = new Dog[]{};

Note: the declared array data type is Animal, but the Dog array is actually assigned. Every Dog object can be safely converted to Animal. The transition from Dog to Animal is up the inheritance chain and is therefore covariant

2. Covariant and contravariant in a delegate

1. Covariant in delegation

// The return value of the delegate definition is Animal The type is the parent class 
public delegate Animal GetAnimal();
// The return value in the delegate method implementation is Dog , it is a subclass
static Dog GetDog(){return new Dog();}
//GetDog The return value of is Dog, Dog is Animal The subclass. return 1 a Dog It must be the same as going back 1 a Animal ; So the assignment to the delegate below is valid
GetAnimal getMethod = GetDog;


2. Contravariant in the delegate

// The definition parameter type in the delegate is Dog
public delegate void FeedDog(Dog target);
// The parameter type in the actual method is Animal
static void FeedAnimal(Animal target){}
// FeedAnimal is FeedDog A valid way to delegate, because the type of argument the delegate accepts is Dog ; while FeedAnimal The accepted parameter is animal . Dog It can be implicitly converted to Animal , so the delegate can safely do the type conversion, the correct execution of the delegate method;
FeedDog feedDogMethod = FeedAnimal;
// When you define a delegate, the arguments are subclasses; in fact, the arguments to the delegate method are broader superclasses Animal , is the superclass to subclass direction, is contravariant


3. Covariant and contravariant of generic delegates

1. Contravariant in generic delegation

// Statement of Authorization: 
public delegate void Feed<in T>(T target);
//Feed Entrusted to accept 1 Three generic types T , notice in the Angle bracket of the generic type 1 a in Keyword. The purpose of this keyword is to tell the compiler what type to assign to a delegate T You might have to do contravariant // First statement 1 a T for Animal The commission
Feed<Animal> feedAnimalMethod = a=>Console.WriteLine( " Feed animal lambda " );
// will T for Animal Delegate assignment to T for Dog This is legal because when you define a generic delegate in Keywords if put in Remove the keyword and the compiler will consider it illegal
Feed<Dog> feedDogMethod = feedAnimalMethod;


2. Covariant in generic delegates

// Entrusting statement 
public delegate T Find<out T>();
//Find The delegate has to return 1 Three generic types T In the Angle brackets of a generic type 1 a out Keyword, the keyword indicates T The type may be covariant
// The statement Find<Dog> entrust
Find<Dog> findDog = ()=>new Dog();
// The statement Find<Animal> Delegate and will findDog Assigned to findAnimal It's legal. Type T from Dog to Animal Transitions are covariant
Find<Animal> findAnimal = findDog;


4. Covariant and contravariant in generic interfaces

1. Contravariant in generic interfaces

// Interface definition: 
public interface IFeedable<in T>
{
void Feed(T t);
} // Generics of interfaces T Before a 1 a in Keyword to indicate that the generic interface may be contravariant
//如下泛型类型FeedImp<T> , to implement the generic interface above; Note the covariant and contravariant keywords in public class FeedImp<T>:IFeedable<T>
{
    public void Feed(T t){
        Console.WriteLine( " Feed Animal " );
    }
} // Using interface inverter:
IFeedable<Dog> feedDog = new FeedImp<Animal>();
// The above code will FeedImp<Animal> The type assignment is given IFeedable<Dog> The variables; Animal to Dog It transforms, so it's contravariant


2. Covariant in generic interfaces

// Definition of interface: 
public interface IFinder<out T>
{
    T Find();
} // Generics for generic interfaces T Before using the out Keywords to illustrate the interface is possible to do covariant; The following generic interface implementation class
public class Finder<T>:IFinder<T> where T:new()
{
    public T Find(){
        return new T();
    }
}  // The use of covariance ,IFinder The generic type of is Animal But because there is out Keyword, I can be Finder<Dog> Assign a value to it
IFinder<Animal> finder = new Finder<Dog>();

I hope this article has been helpful for your C# programming.


Related articles: