变体泛型接口(Variant Generic Interfaces)
协变 out
可以将具有派生程度更大(更具体)的类型的泛型,转为具有派生程度更小(更抽象)的类型的泛型
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
   | public interface ICovariant<out T> { 	T GetSome();
  	void Todo(Action<T> action); }
  public class MyCovariant<T> : ICovariant<T> { 	public T GetSome() 	{ 		return default<T>; 	}
  	public void Todo(Action<T> action) 	{ 		 	} }
  public class Base {
  }
 
  public class Child : Base {
  }
  public class Program { 	public static void Main(string[] args) 	{ 		 		ICovariant<Child> childs = new MyCovariant<Child>();
  		 		ICovariant<Base> bases = childs; 	} }
   | 
 
逆变 in
可以将具有派生程度更小(更抽象)的类型的泛型,转为具有派生程度更大(更具体)的类型的泛型
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
   | public interface IContravariant<in T> { 	void SetSome(T param);
  	void Todo(Func<T> action); }
  public class MyContravariant<T> : IContravariant<T> { 	public void SetSome(T param) 	{ 		 	}
  	public void Todo(Func<T> action) 	{ 		 	} }
  public class Base {
  }
 
  public class Child : Base {
  }
  public class Program { 	public static void Main(string[] args) 	{ 		 		IContravariant<Base> bases = new MyContravariant<Base>();
  		 		IContravariant<Child> childs = bases; 	} }
   | 
 
PS:
协变和逆变属于可变泛型,常规的泛型属于固定泛型;
可变泛型仅可在接口和委托之间转换,无法在其实现类上转换,因为可变泛型接口的实现类为固定泛型。