ジェネリックな共分散と逆分散はC#4.0でどのように実装されますか?


106

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

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

C#4.0の詳細を説明できる人はいますか?


ここではC#4.0に代表者とのインターフェイス上で、今後共分散とコントラ分散の実装をカバーして良い記事です:LINQファーム:C#4.0での共変性と反変性
CMS

AndersNoråseがC# 4.0- 共分散と逆分散の概念を説明し、.NET 2.0以降、ILですでにサポートされていることを示しています。
Thomas Freudenberg、

回答:


155

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

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

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

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

これで多少問題が解消されることを願っています。意味がわからない場合はお知らせください。


3
それでは、クラスが「List <out T>」として宣言されている場合、「void Add(T obj)」のようなメンバー関数を持つべきではないということですか?C#4.0コンパイラはそのエラーを報告しますよね?
モーガンチェン

1
モーガン:はい、確かに私の理解です。
Jon Skeet、

4
ここでも、SOに関するあなたの回答の1つがすぐにコードの改善に役立ちました。ありがとうございました!
マーク

@アークくん:はい、私はそれを知っています。したがって、同じ文で「まだ機能しません」。(そして私もその理由を知っています。)
Jon Skeet 2013年

@JonSkeet @ Ark-kunが言ったList<Banana>ように、IList<Fruit>「aはa としてのみ使用できる」というのは正しいことですか。もしそうなら、これはどのようにして可能ですか?ただし、IList<T>インターフェイスのタイプパラメータは共変として定義されていません(いいえout T、ただし単にT)。
gehho 2013年

5

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

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.