108

私は PDC 2008 には参加しませんでしたが、C# 4.0 がジェネリック共分散と反分散をサポートすると発表されたというニュースを耳にしました。つまり、List<string>に割り当てることができますList<object>。それはどうしてですか?

Jon Skeet の著書C# in Depthでは、C# ジェネリックが共分散と反分散をサポートしない理由が説明されています。主に安全なコードを書くためのものです。現在、C# 4.0 はそれらをサポートするように変更されました。それは混乱をもたらすでしょうか?

C# 4.0 の詳細を知っている人はいますか?

4

2 に答える 2

157

Variance は、安全な方法でのみサポートされます。実際には、CLR が既に持っている機能を使用します。List<Banana>したがって、本で a を aとして(またはそれが何であれ)使用しようとした例はList<Fruit>まだ機能しませんが、他のいくつかのシナリオでは機能します。

まず、インターフェイスとデリゲートでのみサポートされます。

次に、インターフェイス/デリゲートの作成者が型パラメーターをin(反変性の場合) またはout(共変性の場合) として修飾する必要があります。最も明白な例はIEnumerable<T>、値を「取り出す」ことだけを許可するもので、新しい値を追加することはできません。となりIEnumerable<out T>ます。これは型の安全性をまったく損なうものではありませんが、たとえばIEnumerable<string>return と宣言されたメソッドからを返すことができIEnumerable<object>ます。

反変性は、インターフェイスを使用するための具体的な例を示すのが難しいですが、デリゲートを使用すると簡単です。考慮してください-それはパラメーターAction<T>を取るメソッドを表すだけです。をas としてT使用してシームレスに変換できると便利です。パラメーターを受け取るメソッドは、代わりに a が表示されている場合は問題ありません。もちろん、C# 2 には既にある程度のデリゲートの共分散と反分散がありますが、あるデリゲート型から別の型への実際の変換 (新しいインスタンスの作成) を介して - 例については P141-144 を参照してください。C# 4 では、これがより一般的なものになり、(私が信じている) 変換のために新しいインスタンスを作成することが回避されます。(代わりに参照変換になります。)Action<object>Action<string>objectstring

これで少しは解決することを願っています。意味が分からない場合はお知らせください。

于 2008-10-29T08:16:55.220 に答える
5

Jonがまだ取り上げていないわけではありませんが、EricLippertのブログやビデオへのリンクをいくつか紹介します。彼は例を挙げてそれを説明する素晴らしい仕事をしています。

https://blogs.msdn.microsoft.com/ericlippert/2007/10/16/covariance-and-contravariance-in-c-part-one/

ビデオ:

https://www.youtube.com/watch?v=3MQDrKbzvqU

https://www.youtube.com/watch?v=XRIadQaBYlI

https://www.youtube.com/watch?v=St9d2EDZfrg

于 2010-04-16T16:24:07.770 に答える