The transition from a subclass to a parent class is covariant, identified by the Out keyword, and transformed from the parent class to the subclass in the inverse, with the In keyword
The application of covariant and inverse transformation
One, the covariance of the array
Animal[] animalArray =
new
Dog[]{};
说明:声明的数组数据类型是Animal,而实际上赋值时给的是Dog数组;每一个Dog对象都可以安全的转变为Animal。Dog向Animal方法转变是沿着继承链向上转变的所以是协变
二. 委托中的协变和逆变
1、委托中的协变
C# 代码 复制
//委托定义的返回值是Animal类型是父类public delegate Animal GetAnimal();//委托方法实现中的返回值是Dog,是子类static Dog GetDog(){return new Dog();}//GetDog的返回值是Dog, Dog是Animal的子类;返回一个Dog肯定就相当于返回了一个Animal;所以下面对委托的赋值是有效的GetAnimal getMethod = GetDog;
2, the inverter in the delegation
C # codeCopy
the definition parameter type in the delegate is the dog publicdelegatevoid Feeddog (dog target); the parameter type in the actual method is Animalstaticvoid Feedanimal (Animal target){}// Feedanimal is a valid method of Feeddog delegate, because the parameter type accepted by the delegate is dog, and Feedanimal accepts the argument that Animal,dog can be implicitly converted to animal, so the delegate can do the type conversion safely, and execute the delegate method correctly. ;= feedanimal; When defining a delegate, the parameter is a subclass, in fact the parameter of the delegate method is the broader parent class animal, is the parent class to the subclass direction Change, is the inverse variable
Three. Covariance and contravariance of generic delegates
1, the inverse of the generic delegate
C # codeCopy
Delegate declaration:publicdelegatevoid feed< in T>//Feed delegate accepts a generic type T, Note that there is an in keyword in the angle brackets of the generic, which is the function of telling the compiler that type T may have to be reversed when assigning a delegate value // Declare a delegate Feed of T-Animal <Animal >= a+Console.WriteLine ("Feed Animal Lambda"); It is legal to assign a delegate of T to animal to a delegate variable that is a Dog, because the IN keyword is defined when you define a generic delegate, and if you remove the In keyword, the compiler will consider an illegal Feed<Dog >=
2. Covariance in generic delegates
C # codeCopy
Delegate declaration publicDelegate t find<out T>//find delegate to return an instance of a generic type T, There is an out keyword in the angle brackets of the generic, which indicates that the T type is likely to be covariant // declared find<dog> delegate Find<Dog>= ()=new Dog (); declaring a find<animal> delegate and assigning Finddog to Findanimal is legal, and the type T from dog to Animal is covariant Find<Animal >=
Four Covariance and contravariance in generic interfaces
1, the inverter in the generic interface
C # codeCopy
//Interface Definition:Public InterfaceIfeedable<InchT>{voidFeed (T-t);} //An in keyword before the generic t of the interface to indicate that the generic interface might have to be contravariant// The following generic type Feedimp<t> To implement the above generic interface; Note that covariant and contravariant keywords in public class Feedimp < T ; : ifeedable < T ; { public void Feed (t t) {Console.WriteLine ("Feed Animal");} } // using interface inversion: ifeedable < Dog ; feeddog = new feedimp < Animal ; (); The code above // assigns the feedimp<animal> type to the ifeedable<dog> variable; Animal changes to the Dog, so it's the inverse.
2. Covariance in generic interfaces
C # codeCopy
//Definition of the interface:Public InterfaceIfinder<OutT> {T Find ();} The // generic interface's generic t was preceded by an out keyword to indicate that this interface is likely to be covariant; The following generic interface implementation class public class Finder < T ; : Ifinder < T ; where T: New () { public T Find () { return new T ();} } // uses covariant, Ifinder's generic type is animal, but because of the Out keyword, I can assign the finder<dog> to it Ifinder < Animal ; finder = new finder < Dog > ();
C # covariance and contravariance