泛型之逆变和协变总结
泛型之逆变和协变总结
变的概念
- //父类 = 子类
- string str = "string";
- object obj = str;//变了
协变(Foo<父类> = Foo<子类> )
- //泛型委托:
- public delegate T MyFuncA<T>();//不支持逆变与协变
- public delegate T MyFuncB<out T>();//支持协变
-
- MyFuncA<object> funcAObject = null;
- MyFuncA<string> funcAString = null;
- MyFuncB<object> funcBObject = null;
- MyFuncB<string> funcBString = null;
-
- funcAObject = funcAString;//编译失败,MyFuncA不支持逆变与协变
- funcBObject = funcBString;//变了,协变
逆变(Foo<子类> = Foo<父类>)
- public delegate void MyActionA<T>(T param);//不支持逆变与协变
- public delegate void MyActionB<in T>(T param);//支持逆变
-
- MyActionA<object> actionAObject = null;
- MyActionA<string> actionAString = null;
- MyActionB<object> actionBObject = null;
- MyActionB<string> actionBString = null;
-
- actionAString = actionAObject;//MyActionA不支持逆变与协变,编译失败
- actionBString = actionBObject;//变了,逆变
-
在泛型参数上添加了in关键字作为泛型修饰符的话,那么那个泛型参数就只能用作方法的输入参数,或者只写属性的参数,不能作为方法返回值等,总之就是只能是“入”,不能出。out关键字反之。
逆变与协变的相互作用
- public interface IBar<in T> { }
- //应该是in
- public interface IFoo<in T>
- {
- void Test(IBar<T> bar);
- }
- //还是out
- public interface IFoo<out T>
- {
- void Test(IBar<T> bar);
- }
有协变能力的IFoo要求它的泛型参数(IBar)有逆变能力
只要心中有梦,不管什么天气都适合睡觉