C#笔记16:协变与逆变
本章概要:
1:协变与逆变概念
2:协变
3:逆变
4:注意事项
5:接口变体语法
1:逆变与协变概念
“协变”是指能够使用与原始指定的派生类型相比,派生程度更大的类型。
“逆变”则是指能够使用派生程度更小的类型。
如果泛型接口或委托的泛型参数声明为协变或逆变,则将该泛型接口或委托称为“变体”。
2:协变
查看下面代码:
IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;
在 .NET Framework 早期版本中,在 Option Strict On 条件下,此代码会导致 C# 和 Visual Basic 中出现编译错误。但是现在,您可以使用 strings 代替 objects,如上例所示,因为 IEnumerable<(Of <(T>)>) 接口为协变接口。
3:逆变
逆变允许方法具有与接口的泛型形参所指定的实参类型相比,派生程度更小的实参类型。为展示逆变功能,假设您已创建 BaseComparer 类来比较 BaseClass 类的实例。BaseComparer 类实现 IEqualityComparer<BaseClass>(在 Visual Basic 中为 IEqualityComparer(Of BaseClass))接口。因为 IEqualityComparer<(Of <(T>)>) 接口现在为逆变接口,所以您可以使用 BaseComparer 来比较继承 BaseClass 类的类的实例。以下代码示例中演示了这一点。
// Simple hierarchy of classes. class BaseClass { } class DerivedClass : BaseClass { } // Comparer class. class BaseComparer : IEqualityComparer<BaseClass> { public int GetHashCode(BaseClass baseInstance) { return baseInstance.GetHashCode(); } public bool Equals(BaseClass x, BaseClass y) { return x == y; } } class Program { static void Test() { IEqualityComparer<BaseClass> baseComparer = new BaseComparer(); // Implicit conversion of IEqualityComparer<BaseClass> to // IEqualityComparer<DerivedClass>. IEqualityComparer<DerivedClass> childComparer = baseComparer; } }
4:注意事项
有引用类型才支持使用泛型接口中的变体。值类型不支持变体。 实现变体接口的类仍是固定类。例如,虽然 List<(Of <(T>)>) 实现协变接口 IEnumerable<(Of <(T>)>),但无法将 List<string>.
// The following line generates a compiler error // because classes are invariant. // List<Object> list = new List<String>(); // You can use the interface object instead. IEnumerable<Object> listObjects = new List<String>();
5:接口变体语法
若要声明变体泛型接口,可以对泛型类型参数使用 in 和 out 关键字。
您可以使用 out 关键字,将泛型类型参数声明为协变。
您可以使用 in 关键字,将泛型类型参数声明为逆变。
NET C# 入门级 | .NET C# 专业级 | .NET 架构级 | BS系统专业级 | BS系统安全 |
1.开篇及C#程序、解决方案的结构 2.源码管理之TFS入门 3.打老鼠初级 …… 21.CMS之主要功能实现 22.进程和线程基础 23.类型转换 24.算法基础 25.初级课程之剩余知识点 |
1.消灭打老鼠游戏中的自定义委托 2.垃圾回收 3.Dispose模式 …… 16.异常使用指导 17.最常用的重构指导 18.Debug和IDE的进阶 19.Resharper的使用 20.ILSPY的使用 |
1.Socket入门 2.打造打老鼠游戏网络版 3.WCF入门 …… 10.依赖注入 11.万物兼可测试 12.软件指标之覆盖率计算 13.软件指标之代码行 14.软件指标之圈复杂度、嵌套深度 |
1.HTML 2.WebForm原理 3.CSS必知必会 …… 19.让浏览器缓存Shop 20.Asp.net的生命周期 21.Asp.net网站的发布以及调试晋级 22.BS程序的本质 23.压力测试我们的Shop |
1.Fiddler必知必会 2.IE开发者工具必知必会 3.跨站脚本防范 4.权限欺骗防范 5.参数越界防范 6.会话劫持防范 7.CSRF防范 8.盗链防范 9.静态文件的保护 |