协变 和 逆变
NET Framework 4 引入了对多种现有泛型接口的变体支持。变体支持允许对实现这些接口的类进行隐式转换。下列接口现在为变体:
-
IEnumerable< T>(T 为协变)
-
IEnumerator< T>(T 为协变)
-
IQueryable< T>(T 为协变)
-
IGrouping< TKey, TElement>( TKey 和 TElement 为协变)
-
IComparer< T>(T 为逆变)
-
IEqualityComparer< T>(T 为逆变)
-
IComparable< T>(T 为逆变)
协变允许方法具有与接口的泛型类型参数所定义的返回类型相比,派生程度更大的返回类型
逆变允许方法具有与接口的泛型形参所指定的实参类型相比,派生程度更小的实参类型
只有引用类型才支持使用泛型接口中的变体。值类型不支持变体。例如,无法将 IEnumerable<int> 隐式转换为 IEnumerable<object>(
实现变体接口的类仍是固定类。例如,虽然 List< T>实现协变接口 IEnumerable< T>,但无法将 List<Object> 隐式转换为 List<String>()
协变接口
interface IRetrieveWrapper<out T>{ T GetData();} //out 关键字是协变接口的关键字
Wrapper<int> intWrapper = new Wrapper<int>(); // Wrapper 类实现了 IRetrieveWrapper 接口
IStoreWrapper<int> storedIntWrapper = intWrapper;
IRetrieveWrapper<Object> retrievedObjectWrapper = intWrapper; //由于是协变接口 , 所以可以从 <int> 泛型转换成 <Object> 泛型
逆变接口
interface IRetrieveWrapper<in T>{ T GetData();} //in 关键字是逆变接口的关键字
Wrapper<Object> intWrapper = new Wrapper<Object>(); // Wrapper 类实现了 IRetrieveWrapper 接口
IStoreWrapper<Object> storedIntWrapper = intWrapper;
IRetrieveWrapper<int> retrievedObjectWrapper = intWrapper; //由于是逆变接口 , 所以可以从 <Object> 泛型转换成 <int>泛型