我最近为我实现的一些自定义用户控件添加了一个界面。界面非常基本。它有一种支持链接的方法:
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())
someCustomControl
是 MyCustomControl
实现IMyInterface(Of MyCustomControl)
而不是 IMyInterface(Of WebControl)
.我在第二行收到此错误(我尝试添加
someCustomControl
):Option Strict On disallows implicit conversions from 'MyCustomControl' to 'IMyInterface(Of WebControl)'.
有没有办法解决这个错误?我已经接近让它工作了,但我对泛型的了解还不够,无法超越这一点。
最佳答案
协方差是 VS 2010 中引入的一种语言功能,可以解决您的问题。您需要定义您的泛型,以便类型 T
有Out
前面的关键字:
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 上的更多信息:
关于vb.net - 泛型、接口(interface)和强制转换问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17031113/