コード内:
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)も実装します。Self
T
Return This
TMe
ISelf(Of theirOwnTypes)
ISelf
IMoe
ILarry
ICurly
ISelfAndMoe(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 implement
IMoe , and
param.Self would implement
ILarry , and
param.Self.Self would implement
ICurly . Further, if the class implements the expected pattern, one could cast
param to e.g.
ISelfAndCurly(Of IMoe) , if one wanted to call a routine which needed those two interfaces but didn't need
ILarry` (このようなキャストは、実装が予期しないことを行った場合に失敗する可能性がありますが、オブジェクトのクラスが次の場合は成功するはずです期待されるパターン)。