1 / 17
文档名称:

Visual Basic 2010中的泛型协变和逆变.doc

格式:doc   页数:17
下载后只包含 1 个 DOC 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

Visual Basic 2010中的泛型协变和逆变.doc

上传人:zbfc1172 2013/1/6 文件大小:0 KB

下载得到文件列表

Visual Basic 2010中的泛型协变和逆变.doc

文档介绍

文档介绍:Visual Basic 2010中的泛型协变和逆变
Visual Studio 2010 有一项名为泛型协变和逆变的新功能,可以用来处理泛型接口和委托。在 Visual Studio 2010 和 Microsoft .NET Framework 4 之前的版本中,在子类型化方面,泛型的行为是不变的,因此类型参数不同的泛型类型不能相互转换。
例如,如果尝试将 List(Of Derived) 传递给接受 IEnumerable(Of Base) 的方法,将会出现错误。但 Visual Studio 2010 可以处理类型安全的协变和逆变,类型安全的协变和逆变支持泛型接口和委托类型上的协变和逆变类型参数声明。在本文中,我将具体讨论这一功能,并介绍如何在应用程序中使用这一功能。
因为按钮是控件,根据基本的面向对象继承原则,您可能认为下面的代码可以正常运行:
Dim btnCollection As IEnumerable(Of Button) = New List (Of Button) From {New Button}
Dim ctrlCollection As IEnumerable(Of Control) = btnCollection
尽管这在 Visual Studio 2008 中是不允许的,并会给出错误“IEnumerable(Of Button) 无法转换为 IEnumerable(Of Control)”。但作为面向对象编程人员,我们知道 Button 类型的值可以转换为控件, 因此如前所述,根据基本继承原则,这段代码应该是可以使用的。
请看下面的例子:
Dim btnCollection As IList(Of Button) = New List(Of Button) From {New Button}
Dim ctrlCollection As IList(Of Control) = btnCollection
ctrlCollection(0) = New Label
Dim firstButton As Button = btnCollection(0)
这段代码会失败并引发 InvalidCastException,因为编程人员将 IList(Of Button) 转换为 IList (Of Control),然后向其中插入一个完全不是按钮的控件。
Visual Studio 2010 可以识别并允许类似第一个示例的代码, Framework 4 时,仍可以不允许类似第二个示例的代码。对于大多数用户,在大部分时间里,程序将以预期的方式运行,不需要进一步深究。但在本文中,我将进一步说明这些代码如何才能正常运行以及其中的原因。
协变
第一段代码将 IEnumerable(Of Button) 视为 IEnumerable(Of Control),为什么在 Visual Studio 2010 中这是代码安全的?第二个代码示例将 IList(Of Button) 视为 IList(Of Control),为什么这不是安全的?
第一段代码是安全的,原因在于 IEnumerable(Of T) 是“输出”接口,也就是说,在 IEnumerable (Of Control) 中,接口用户只是从列表中读取控件。
第二段代码不是安全的,原因在于,IList(Of T) 是“输入输出”接口,因此在 IList(Of Control) 中,接口用户可以读取控件,也可以写入控件。
Visual Studio 2010 支持这种代码的新语言功能称为泛型协变。 Framework 4 中, Microsoft 重新编写了框架的以下代码行:
Interface IEnumerable(Of Out T)
...
End Interface
Interface IList(Of T)
...
End Interface
IEnumerable(Of Out T) 中的 Out 批注指示,如果 IEnumerable 中有方法使用到 T,T 只能用在输出位置,如函数返回的输出位置或只读属性类型的输出位置。这样,用户可以将任意 IEnumerable(Of Derived) 转换为 IEnumerable(Of Base),而不会引发 InvalidCastException。
IList 没有批注,这是因为 IList(Of T) 是输入输出接口。这样,用户不能将 IList(Of Derived) 转换为 IList(Of Base),反之亦然;如前所述,这样会引发 InvalidCastException。逆变
Out 批注有一个相对的批注。这并