3

ジェネリッククラスがありますCommand(Of T)

コマンドは(部分的に)次のように定義されます:

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

すべてのコマンドのリストを作成したいのですが、オブジェクトが渡されたら、の呼び出しがtrueを返すA私のと同じジェネリック型のすべてのコマンドを引き出しますACondition(A)

できます

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))

私は何が欠けていますか?

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

これは、ジェネリック型がメソッドの入力としてのみ使用され、出力refまたはoutputパラメーターとして使用されない場合にのみ (図のように) 機能します。

于 2012-12-23T01:09:23.867 に答える