我已经为两个名为表和字段的父类实现了继承。每个父类都有几个子类。在表父类中,我创建了一个期望参数列表(字段)的方法。
尝试将参数 List(Of ChildField)传递给期望参数 List(Of Field)的方法时出错。错误消息如下:
类型的价值 “System.Collections.Generic.List(中 com.hlb.icisbatch.data.ChildField)“
无法转换为 “System.Collections.Generic.List(中 com.hlb.icisbatch.data.Field)'
我的问题,是否可以将子类列表作为参数传递?如果它不是一个列表,那么它工作正常。但不知何故,列表无法实现?
以下是示例类结构:
Table Field
| |
ChildTable ChildField
我在父类中有一个方法:
Public Class Table
Public Sub New()
End Sub
Public Overridable Sub setFields(ByVal list As List(Of Field)
'Do work here'
End Sub
End Class
子类中的和方法:
Public Class ChildTable
Public Sub New(ByVal list As List(Of ChildField)
setFields(ChildField)
End Sub
End Class
答案 0 :(得分:1)
不,这是不可能的 - 而且有充分的理由。考虑如果调用代码试图将Field
(或其他某些派生类)的实例添加到列表中会发生什么。不好的事情会发生。
在.NET 4(可能是VB10)中,这可以通过通用委托和接口(而不是类)的协方差和逆变来实现 - 但只能在安全的地方。因此IList(Of T)
不是变体(因为值在API的“in”和“out”中); IEnumerable(Of T)
是协变的(因此从IEnumerable(Of String)
转换为IEnumerable(Of Object)
)并且IComparer(Of T)
是逆变的(因此从IComparer(Of Object)
转换为IComparer(Of String)
例如)。
(从v2.0开始,这种能力实际上已经在CLR中,但它只出现在.NET 4的语言和框架中。)
答案 1 :(得分:0)
因此,对于.Net 4.0+(可能也是早期版本),您必须更改setFields方法:
Public Overridable Sub setFields(As T Of Field)(ByVal list As List(Of T)
'Do work here'
End Sub
然后当你用:
打电话时Public Sub New(ByVal list As List(Of ChildField)
setFields(list)
End Sub
它本质上是在呼唤:
setFields(Of ChildField)(list)
这意味着setFields知道它正在处理一个ChildField对象列表,并且不会让任何人做任何顽皮的事情,比如添加一个不同的ChildNumber2Field对象。
尽管.Net 2.0中引入了泛型,但我不确定该版本究竟是多么先进。