变体泛型接口(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:
协变和逆变属于可变泛型,常规的泛型属于固定泛型;
可变泛型仅可在接口和委托之间转换,无法在其实现类上转换,因为可变泛型接口的实现类为固定泛型。