私は出席しませんでしたPDC 2008、しかし、C#4.0が一般的な共分散と反分散をサポートすると発表されたというニュースを聞きました。つまり、List<string>
をList<object>
。それはどうですか?
Jon Skeetの本C#in Depthでは、C#ジェネリックが共分散と反分散をサポートしていない理由が説明されています。主に安全なコードを書くためです。現在、C#4.0はそれらをサポートするように変更されました。それは混乱をもたらすでしょうか?
C#4.0の詳細を知っている人はいますか?
分散はsafeの方法でのみサポートされます-実際には、CLRが既に持っている能力を使用します。したがって、List<Banana>
をList<Fruit>
(またはそれが何であれ)として使用しようとする本で私が挙げた例はまだ機能しませんが、他のいくつかのシナリオは機能します。
まず、インターフェイスとデリゲートでのみサポートされます。
第二に、インターフェース/デリゲートの作成者は、型パラメーターをin
(反分散の場合)またはout
(共分散の場合)として修飾する必要があります。最も明白な例はIEnumerable<T>
で、これは値を「出力」することしかできません-新しい値を追加することはできません。それはIEnumerable<out T>
になります。これは型の安全性を損なうものではありませんが、たとえばIEnumerable<string>
を返すように宣言されたメソッドからIEnumerable<object>
を返すことができます。
共分散は、インターフェイスを使用するための具体的な例を挙げるのが難しいですが、デリゲートを使用すると簡単です。 Action<T>
を考慮してください-これは、T
パラメーターをとるメソッドを表すだけです。 Action<object>
をAction<string>
としてシームレスに使用できるように変換できると便利です。object
パラメータを使用するメソッドは、string
代わりに。もちろん、C#2は既にある程度の委任の共分散と反分散を持っていますが、委任タイプから別のタイプへの実際の変換(新しいインスタンスの作成)を介して-例についてはP141-144を参照してください。 C#4はこれをより一般的なものにし、(私は信じている)変換のための新しいインスタンスの作成を避けます。 (代わりに参照変換になります。)
これで少し解消されることを願っています-意味をなさない場合はお知らせください!
Jonがまだそれをカバーしていないわけではありませんが、Eric Lippertのブログやビデオへのリンクをいくつか紹介します。彼はそれを例で説明する素晴らしい仕事をしています。
https://blogs.msdn.Microsoft.com/ericlippert/2007/10/16/covariance-and-contravariance-in-c-part-one/
ビデオ:
https://www.youtube.com/watch?v=3MQDrKbzvq