コード内:
Interface ISelf(Of Out TMe)
End Interface
Class SomeBase
Implements ISelf(Of SomeBase)
End Class
Class SomeDerived
Inherits SomeBase
Implements ISelf(Of SomeDerived)
End Class
Module ISelfTester
Sub TestISelf()
Dim z7 As New SomeDerived
Dim z8 As ISelf(Of SomeDerived)
Dim z9 As ISelf(Of ISelf(Of SomeDerived))
z8 = z7
z9 = z8
z9 = z7 ' Why is this illegal?
End Sub
End Module
Z7 から Z9 への直接代入は、「エラー 13 Option Strict On は、'wokka.SomeDerived' から 'wokka.ISelf(Of wokka.ISelf(Of wokka.SomeDerived))' への暗黙的な変換を許可しません」というメッセージを生成します。これは、変換があいまいであるためです。 ." Z7 から Z8 へ、または Z8 から Z9 への割り当てよりも、その割り当てがどのようにあいまいになるのでしょうか? 私が知る限り、3 つの代入はすべて表現を維持する変換でなければなりません。つまり、3 つすべてが Z7 と同じオブジェクトへの参照を単純に格納する必要があります。
SomeDerivedのインスタンスを type の参照に割り当てようとしている場合ISelf(Of ISelf(Of SomeBase))、そのインターフェイスのメンバーにアクセスしようとすると、SomeBaseまたはSomeDerived; メンバーが戻り値の型を持つメソッドである場合、TMeそのようなあいまいさがコンパイルの失敗を引き起こす可能性があることを理解できました (コンパイラーは戻り値の型が何であるかを知らないため)。ただし、割り当てが参照型変数への参照の直接ストア以外のものとして解釈できない可能性があることを考えると、「あいまいさ」のために単に参照を割り当てようとすると失敗するのはなぜですか?
ところで、意図された使用法は、 typeISelf(Of T)の読み取り専用プロパティを含めることであり、そのために予想される実装は[すべてのケースで表現を維持する変換; にクラス制約を追加する必要があったと思いますが、元の問題には影響しません]。実装に関心のあるさまざまなクラスがある場合、の共分散を利用して、他の方法では困難ないくつかのことを容易にすることができるはずです [たとえば、各クラスが実装に関心がある場合など。対応するクラス、ISelfAndLarry(Of ItsOwnType)、および/または ISelfAndCurly(Of ItsOwnType)も実装します。SelfTReturn ThisTMeISelf(Of theirOwnTypes)ISelfIMoeILarryICurlyISelfAndMoe(Of ItsOwnType), etc. then one can accept a parameter type which is known to implement any combination of those interfaces e.g.ISelfAndMoe(Of ISelfAndLarry(Of ICurly)) param . Given that declaration,param would implementIMoe , andparam.Self would implementILarry , andparam.Self.Self would implementICurly . Further, if the class implements the expected pattern, one could castparam to e.g.ISelfAndCurly(Of IMoe) , if one wanted to call a routine which needed those two interfaces but didn't needILarry` (このようなキャストは、実装が予期しないことを行った場合に失敗する可能性がありますが、オブジェクトのクラスが次の場合は成功するはずです期待されるパターン)。