我有一个通用类Command(Of T)
命令(部分)定义为:
Public Class Command(Of T As BaseType)
Inherits Command
Public Property Condition As Func(Of T, Boolean)
End Class
我想创建一个包含所有命令的列表,然后当我递交一个对象A
时,拉出所有与我的A
具有相同泛型类型的命令,并调用Condition(A)
1}}返回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))
由于CommandsOfTypeA是List(Of Command)
而不是List(Of Command(Of DerivedType))
我错过了什么?
答案 0 :(得分:1)
问题是虽然DerivedType
的实例是BaseType
的实例,但这并不一定意味着Command(Of DerivedType)
的实例是Command(Of BaseType)
的实例}。默认情况下,不考虑类型层次结构的泛型类型参数。
在编程语言理论中,启用此功能的功能称为covariance。
.net 4.0确实有一些支持,虽然它只能应用于接口,而不是类。 Here是关于该主题的一些文档。
基本上,它看起来像这样:
Interface ICovariant(Of Out R)
Function GetSomething() As R
' The following statement generates a compiler error.
' Sub SetSomething(ByVal sampleArg As R)
End Interface
当您的通用类型仅用作方法输入,从不输出或ref
或output
参数时,这仅适用于(如图所示)。