泛型之逆变和协变总结

泛型之逆变和协变总结

 

 

变的概念

  1. //父类 = 子类 
  2. string str = "string"
  3. object obj = str;//变了 

协变(Foo<父类> = Foo<子类> )

  1. //泛型委托: 
  2. public delegate T MyFuncA<T>();//不支持逆变与协变 
  3. public delegate T MyFuncB<out T>();//支持协变 
  4.  
  5. MyFuncA<object> funcAObject = null
  6. MyFuncA<string> funcAString = null
  7. MyFuncB<object> funcBObject = null
  8. MyFuncB<string> funcBString = null
  9.  
  10. funcAObject = funcAString;//编译失败,MyFuncA不支持逆变与协变 
  11. funcBObject = funcBString;//变了,协变 

逆变(Foo<子类> = Foo<父类>)

  1. public delegate void MyActionA<T>(T param);//不支持逆变与协变 
  2. public delegate void MyActionB<in T>(T param);//支持逆变 
  3.  
  4. MyActionA<object> actionAObject = null
  5. MyActionA<string> actionAString = null
  6. MyActionB<object> actionBObject = null
  7. MyActionB<string> actionBString = null
  8.  
  9. actionAString = actionAObject;//MyActionA不支持逆变与协变,编译失败 
  10. actionBString = actionBObject;//变了,逆变 
  11.  

在泛型参数上添加了in关键字作为泛型修饰符的话,那么那个泛型参数就只能用作方法的输入参数,或者只写属性的参数,不能作为方法返回值等,总之就是只能是“入”,不能出。out关键字反之。

逆变与协变的相互作用

  1. public interface IBar<in T> { } 
  2. //应该是in 
  3. public interface IFoo<in T

  4. void Test(IBar<T> bar)

  5. //还是out 
  6. public interface IFoo<out T

  7. void Test(IBar<T> bar)

有协变能力的IFoo要求它的泛型参数(IBar)有逆变能力

只要心中有梦,不管什么天气都适合睡觉
原文地址:https://www.cnblogs.com/mmry/p/6262254.html