vb.net - 泛型、接口(interface)和强制转换问题

标签 vb.net generics interface user-controls

我最近为我实现的一些自定义用户控件添加了一个界面。界面非常基本。它有一种支持链接的方法:

Public Interface IMyInterface(Of T As WebControl)
    Function DoSomething() As T
End Interface

实现也很基本:
Public Class MyCustomControl
    Inherits CompositeControl
    Implements IMyInterface(Of MyCustomControl)

Public Function DoSomething() As MyCustomControl _
    Implements IMyInterface(Of MyCustomControl).DoSomething
    ' do stuff

    Return Me
End Class

到目前为止一切正常。当我尝试遍历所有实现 IMyInterface 的控件集合时,就会出现问题。界面,像这样:
Dim myList = New List(Of IMyInterface(Of WebControl))

myList.Add(someCustomControl)

myList.ForEach(Sub(i) i.DoSomething())
someCustomControlMyCustomControl实现IMyInterface(Of MyCustomControl)而不是 IMyInterface(Of WebControl) .

我在第二行收到此错误(我尝试添加 someCustomControl ):

Option Strict On disallows implicit conversions from 'MyCustomControl' to 'IMyInterface(Of WebControl)'.



有没有办法解决这个错误?我已经接近让它工作了,但我对泛型的了解还不够,无法超越这一点。

最佳答案

协方差是 VS 2010 中引入的一种语言功能,可以解决您的问题。您需要定义您的泛型,以便类型 TOut前面的关键字:

Public Interface IMyInterface(Of Out T As WebControl)
    Function DoSomething() As T
End Interface

When you use the Out keyword, you are using covariance. It allows generics of a more derived type to be used in place of a generic with the base type. So in your case it will allow a IMyInterface(Of MyCustomControl)) object in places where the code would normally expect IMyInterface(Of WebControl)), such as your for loop.

Note that covariance has a restriction. The covariant type T can only be used as a function return value, and not as a parameter into a function (or sub). For example, if the DoSomething signature in IMyInterface looked like this the compiler would complain:

' Here the type T is used as an input param - compiler error
Sub DoSomething(ByVal sampleArg As T)

鉴于您的链接场景,我认为上述限制不是问题。

MSDN 上的更多信息:
  • Covariance and Contravariance
  • Creating Variant Generic Interfaces
  • 关于vb.net - 泛型、接口(interface)和强制转换问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17031113/

    相关文章:

    vb.net - 您如何看待 VB 10 中的多行 lambda

    .net - VB.NET 数组算术

    c# - 单击表单上任何数据 GridView 的保存按钮时提交当前脏单元格

    c# - 使用 Int64 进行通用转换

    scala - 解析 F 有界多态性中的类型

    java - 如何使用泛型类型实现接口(interface)?

    c# - 谁负责检查空引用异常?

    java - 使用自定义 TypeSelector 使用 Gson on Fire 反序列化 Json

    java - 接口(interface)内的 toString、hashcode 和 equals 方法

    c# - C#动态设置界面装饰