が a の代わりにa をList.AsReadOnly()
返すという事実が私にとって困難なケースに遭遇しました。返されたコレクションは のであったため、自動的に にアップキャストできませんでした。これは奇妙に思えたので、.Net ソース コードを確認したところ、このメソッドが に対して行うのとは異なること、つまりインターフェイスではなく具象クラスを返すことを確認しました。ReadOnlyCollection
IReadOnlyCollection
Value
Dictionary
IReadOnlyCollection
AsReadOnly()
List
Dictionary
これがなぜなのか説明できる人はいますか?この不一致があることは、特に可能な場合、特にパブリックの場合にインターフェイスを使用したいため、不利益に思えます。
私のコードでは、コンシューマーは単なるプライベート メソッドであるため、そのパラメーター シグネチャを からIReadOnlyDictionary<T, IReadOnlyCollection<T>>
に変更できると最初は考えていましたIReadOnlyDictionary<T, ReadOnlyCollection<T>>
。しかし、これにより、プライベート メソッドがコレクションの値を変更する可能性があるように見えることに気付きました。そのため、インターフェイスを適切に使用するために、以前のコードに煩わしい明示的なキャストを追加しました。
.ToDictionary(
item => item,
item => (IReadOnlyCollection<T>) relatedItemsSelector(item)
.ToList()
.AsReadOnly() // Didn't expect to need the direct cast
)
ああ、私は常に共分散と反分散を混同しているので、誰かが自動キャストを妨げているものを教えてください。将来のためにそれらを覚えておく方法を賢明な方法で思い出させてください。(たとえば、コレクションは、_____ [入力/出力] パラメーターに対して ______バリアント [co/contra] ではありません。) インターフェイスの実装が多数存在する可能性があり、すべてをキャストするのは安全ではないため、これができない理由を理解しています。ディクショナリの個々の要素を要求された型に変換します。私がこの単純な側面でさえ吹き飛ばしていて、それを理解していない場合を除き、その場合、私を正しく設定するのを手伝ってくれることを願っています...