我目前正在Visual Studio 2013中使用VB on .NET 4.5。我有一个抽象的基类,它包含另一个抽象基类的集合,如下所示:
通用基类:
Public MustInherit Class CustomCollection(Of collectionItemType As CollectionItemBase)
Inherits Collections.ObjectModel.KeyedCollection(Of String, CollectionItemBase)
'...
End Class
通用基类引用的基类:
Public MustInherit Class CollectionItemBase
'...
End Class
我有一组继承泛型基类“CustomCollection”的类:
Public Class Collection1
Inherits CustomCollection(Of ClassThatDerivesFromCollectionItemBase1)
'...
End Class
Public Class Collection2
Inherits CustomCollection(Of ClassThatDerivesFromCollectionItemBase2)
'...
End Class
'etc...
这是我用来尝试将Collection1的实例转换为CustomCollection(Of CollectionItemBase)的代码:
'...
someProperty = instanceOfCollection1.Cast(Of CustomCollection(Of CollectionItemBase))
'...
这会在运行时生成以下错误,这对我来说似乎是无稽之谈:
“无法转换类型的对象 'd__b1`1 [ApplicationName.CustomCollection`1 [ApplicationName.CollectionItemBase]]' 输入 'ApplicationName.CustomCollection`1 [ApplicationName.CollectionItemBase]'“。
似乎声称它无法将对象强制转换为自己的类型。有什么想法吗?
答案 0 :(得分:0)
当您在Cast(Of T)
上使用IEnumerable(Of U)
时,它会将每个元素投射到目标类型,因此您不应传递IEnumerable(Of T)
的类型,而应传递T本身。
在您的情况下,将您的演员表写为
someProperty = instanceOfCollection1.Cast(Of CollectionItemBase)
此演员表会返回您可以使用的IEnumerable(Of CollectionItemBase)
。
但我不认为这是你的问题。让我们把这一行代码放在一边,谈谈你的问题。事实是仿制药不会那样工作。通用类型的基础/派生类型是完全不同的类型。
在最简单的示例中,A(Of T)
的实例即使A(of U)
继承自T
,也无法转换为U
,因为A(Of U)
是不同于'A(Of U)..
用真实的类替换类名:。的实例 Collection1
或者说
CustomCollection(Of ClassThatDerivesFromCollectionItemBase1)
无法转换为
CustomCollection(Of CollectionItemBase)
尽管
ClassThatDerivesFromCollectionItemBase1
Inherits CollectionItemBase
因为
CustomCollection(Of ClassThatDerivesFromCollectionItemBase1)
是与
不同的类型CustomCollection(Of CollectionItemBase).
这与协方差无关,因为(来自MSDN):
在.NET Framework 4中,变体类型参数仅限于 通用接口和通用委托类型。
因此它不适用于敌人类,但适用于接口。让我对您的代码进行一些更改:
Public Class CollectionItemBase
End Class
Public Class ClassThatDerivesFromCollectionItemBase1
Inherits CollectionItemBase
End Class
Public Class ClassThatDerivesFromCollectionItemBase2
Inherits CollectionItemBase
End Class
Public Interface ICustomCollection(Of Out collectionItemType As CollectionItemBase)
End Interface
Public Class Collection1
Implements ICustomCollection(Of ClassThatDerivesFromCollectionItemBase1)
End Class
此行中的Out
修饰符
Public Interface ICustomCollection(Of Out collectionItemType As CollectionItemBase)
使类型参数协变,意味着如果你有
Dim instanceOfCollection1 As New Collection1
这两行将起作用:
Dim x As ICustomCollection(Of CollectionItemBase) = instanceOfCollection1
Dim y As ICustomCollection(Of Item1) = instanceOfCollection1
希望这很有用