35

これを理解しようとしていますが、検索から適切な結果が得られませんでした。

C# 4 でできること

    public interface IFoo<out T>
    {

    }

これはどう違うのですか

    public interface IFoo<T>
    {

    }

私が知っているのoutは、ジェネリック パラメーターを共変 (??) にすることだけです。誰かが部品の使用法を例で説明できますか<out T>? また、クラスではなくインターフェイスとデリゲートにのみ適用されるのはなぜですか?

重複している場合は申し訳ありませんが、重複している場合は閉じてください。

4

3 に答える 3

47

誰かが out T 部分の使用法を例で説明できますか?

もちろん。IEnumerable<T>は共変です。つまり、次のことができます。

static void FeedAll(IEnumerable<Animal> animals) 
{
    foreach(Animal animal in animals) animal.Feed();
}

...

 IEnumerable<Giraffe> giraffes = GetABunchOfGiraffes();
 FeedAll(giraffes);

「共変」とは、型引数の代入互換関係がジェネリック型で保持されることを意味します。Giraffeは と代入互換性があるAnimalため、その関係は構築された型で保持されます:IEnumerable<Giraffe>は と代入互換性がありIEnumerable<Animal>ます。

インターフェイスとデリゲートにのみ適用され、クラスには適用されないのはなぜですか?

クラスの問題は、クラスが可変フィールドを持つ傾向があることです。例を見てみましょう。これを許可したとします。

class C<out T>
{
    private T t;

では、先に進む前に、この質問をよく考えてください。フィールドをデフォルト以外に設定するメソッドをコンストラクターの外に置くことはできますか?C<T>t

タイプセーフである必要がC<T>あるため、T を引数として取るメソッドを使用できなくなりました。T のみを返すことができます。では、誰が t を設定し、設定した値をどこから取得するのでしょうか?

共変クラス型は、クラスがimmutableである場合にのみ機能します。そして、C# で不変クラスを作成する良い方法がありません。

できればよかったのですが、与えられた CLR 型システムと一緒に暮らす必要があります。将来的には、不変クラスと共変クラスの両方をより適切にサポートできるようになることを願っています。

この機能に興味がある場合は、この機能をどのように設計および実装したかについての私の長いシリーズを読むことを検討してください。下から始めます。

https://blogs.msdn.microsoft.com/ericlippert/tag/covariance-and-contravariance/

于 2011-06-28T15:21:11.760 に答える
6

一般的な分散について話している場合:

共分散とは、操作から呼び出し元に返される値に関するものです。

反変性それは反対で、呼び出し元によって渡される値に関するものです。

型パラメーターが出力のみに使用される場合、私が知っていることから、 out を使用できます。ただし、型が入力のみに使用される場合は、in を使用できます。コンパイラは、共分散と呼ばれる形式と反分散と呼ばれる形式を覚えているかどうかを確認できないため、便利です。型が宣言された後にそれらを明示的に宣言しない場合、関連する型の変換が暗黙的に利用可能になります。

入力に型パラメーターのみを使用する (または出力にのみ使用する) クラスがある場合でも、in または out 修飾子を指定できないため、クラスには分散 (共分散または反分散) はありません。バリアント型パラメーターを持つことができるのは、インターフェイスとデリゲートのみです。まず、CLR はそれを許可しません。概念的な観点から、インターフェイスは特定の観点からオブジェクトを見る方法を表しますが、クラスはより実際的な実装タイプです。

于 2011-06-28T15:22:28.687 に答える
5

これは、次のことを意味します。

class Parent { } 
class Child : Parent { }

のインスタンスは のインスタンスでIFoo<Child>もありますIFoo<Parent>

于 2011-06-28T15:13:04.673 に答える