1

我已经为两个名为TableField的父类实现了继承。每个父类都有几个子类。在Table父类中,我创建了一个需要参数List(Of Field)的方法。

尝试将参数List(Of ChildField)传递给需要List(Of Field)参数的方法时出现错误。错误信息如下:

'System.Collections.Generic.List(Of com.hlb.icisbatch.data.ChildField)' 类型的值
无法转换为 'System.Collections.Generic.List(Of 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
4

2 回答 2

1

不,这是不可能的——而且有充分的理由。考虑如果调用代码尝试将Field(或其他派生类)的实例添加到列表中会发生什么。坏事会发生。

在 .NET 4(可能是 VB10)中,这可以通过泛型委托和接口(不是类)的协变和逆变来实现 - 但仅限于安全的地方。所以IList(Of T)不是变体(因为值API 中“输入”和“输出”);IEnumerable(Of T)是协变的(因此存在从IEnumerable(Of String)to的转换IEnumerable(Of Object))并且IComparer(Of T)是逆变的(例如存在从IComparer(Of Object)to的转换IComparer(Of String))。

(此功能实际上自 v2.0 起就已在 CLR 中,但仅在 .NET 4 的语言和框架中出现。)

于 2010-04-12T09:40:36.957 回答
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 中引入了泛型,但我不确定该版本在做这种事情时到底有多先进。

于 2018-02-26T01:15:51.133 回答