3

我有一个通用类Command(Of T)

命令(部分)定义为:

Public Class Command(Of T As BaseType)
    Inherits Command
    Public Property Condition As Func(Of T, Boolean)
End Class

我想创建一个所有命令的列表,然后当我收到一个 objectA时,拉出所有与我的通用类型相同的命令,A调用Condition(A)返回 true

我可以

Dim B As List(Of BaseType)
B.Add(New DerivedType)

Dim C As New List(Of Command(Of BaseType))
C.Add(New Command(Of DerivedType))

引发转换错误。

我可以Command从非泛型对象继承(我们称之为CommandBase...)

Dim C As New List(Of CommandBase)
C.Add(New Command(Of DerivedType))

哪个有效,但现在我无法回到特定于类型的参考。这将获得正确的命令对象:

Dim CommandsOfTypeA = B.Where(function(x) x.GetType.GetGenericArguments(0).FullName = A.GetType.FullName)

但是我现在看不到该怎么做...

Dim MatchingCommands = CommandsOfTypeA.Where(function(x) c.Condition(A))

由于 CommandsOfTypeAList(Of Command)不是List(Of Command(Of DerivedType))

我错过了什么?

4

1 回答 1

1

问题在于,虽然 的实例DerivedType是 的实例BaseType,但这并不一定意味着 的实例Command(Of DerivedType)是 的实例Command(Of BaseType)。默认情况下,泛型类型参数不考虑类型层次结构。

在编程语言理论中,实现这一点的特性称为协方差

.net 4.0 确实对此提供了一些支持,尽管它只能应用于接口,而不是类。 是有关该主题的一些文档。

基本上,它看起来像这样:

Interface ICovariant(Of Out R)
    Function GetSomething() As R
    ' The following statement generates a compiler error. 
    ' Sub SetSomething(ByVal sampleArg As R) 
End Interface

这仅在您的泛型类型仅用作方法输入、从不输出或refoutput参数时才有效(如图所示)。

于 2012-12-23T01:09:23.867 回答