Generic Covariance&はどうですかC#4.0で実装された反分散?
-
05-07-2019 - |
質問
PDC 2008には参加しませんでしたが、C#4.0がGeneric CovarianceおよびContra-Varianceをサポートするために発表されたというニュースを聞きました。つまり、 List< string>
を List< object>
に割り当てることができます。それはどうですか?
Jon Skeetの本 C#の詳細 では、C#ジェネリックが共分散と反分散をサポートしない理由が説明されています。主に安全なコードを書くためです。現在、C#4.0はそれらをサポートするように変更されました。カオスをもたらすだろうか?
C#4.0の詳細を知っている人はいますか?
解決
分散は safe 方法でのみサポートされます-実際には、CLRが既に持っている能力を使用します。したがって、 List< Banana>
を List< Fruit>
(またはそれが何であれ)として使用しようとする本で私が挙げた例はまだ機能しませんが、他にもいくつかのシナリオがあります。
まず、インターフェースとデリゲートでのみサポートされます。
第二に、インターフェイス/デリゲートの作成者は、型パラメーターを in
(反分散)または out
(共分散)として修飾する必要があります。最も明らかな例は、 IEnumerable< T>
です。それの-新しいものを追加することはできません。それは IEnumerable< out T>
になります。これはタイプセーフティをまったく害しませんが、たとえば IEnumerable< object>
を返すように宣言されたメソッドから IEnumerable< string>
を返すことができます。
反変は、インターフェイスを使用するための具体的な例を与えることは困難ですが、デリゲートを使用すると簡単です。 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=3MQDrKbzvqU