-6

これが私の元のスレッドです: C#ジェネリック継承と共分散

読み取り専用インターフェースだけで、継承を機能させたい。

public delegate Boolean EnumerateItemsDelegate<out ItemType>(ItemType item);

public interface IReadOnlyCollection<out ItemType>
{
    Boolean ContainsItem(ItemType item);
    Array CopyToArray();
    void EnumerateItems(EnumerateItemsDelegate<ItemType> enumerateDelegate);

    UInt32 Count { get; }
    UInt32 Capacity { get; }
}

コンパイルする場所を除いて、このように:-p

これが私が働きたいことです:

IReadOnlyCollection<String> s;
IReadOnlyCollection<Object> o = s;
4

1 に答える 1

8

この質問には質問がないようですので、いくつかの質問を作成してお答えします。

共変変換とは何ですか?

明らかな関係を持ついくつかの型Fruitand Appleandがあるとしましょう。などの一種です。BananaAppleFruit

共変変換とは、型引数の変換可能性がジェネリック型の変換可能性を意味するものです。Appleが に変換可能Fruitで、Bowl<Apple>が に変換可能である場合Bowl<Fruit>Bowl<T>は T で共変です。


反変変換とは何ですか?

反変変換は、方向を維持する代わりににする共変変換です。もしが に変換可能なら、は T で反変です。Eater<Fruit>Eater<Apple>Eater<T>


インターフェイスまたはデリゲートを型パラメーターで共変または反変としてマークするにはどうすればよいですか?

共変型パラメータはマークされout、反変型パラメータはマークされinます。

これはニーモニックであることを意図しています。通常、共変インターフェイスでは型パラメーターが出力位置に表示され、反変インターフェイスでは型パラメーターが入力位置に表示されます。


Stringに変換可能Objectです。IReadOnlyCollection<String>に変換可能にするにはどうすればよいIReadOnlyCollection<Object>ですか?

TIReadOnlyCollection<T>で共変にします。マークしoutます。


次のコードを検討してください。

delegate void Action<in T>(T t);
interface IFoo<in X>
{
  void M(Action<X> action);
}

なぜコンパイラはこれが有効ではないと言うのですか?

有効ではないためです。理由を見てみましょう。

class Foo : IFoo<Fruit>
{
  public void M(Action<Fruit> action)
  {
     action(new Apple()); // An apple is a fruit.
  }
}
...
IFoo<Fruit> iff = new Foo();
IFoo<Banana> ifb = iff; // Contravariant!
ifb.M(banana => { banana.Peel(); });

ロジックに従ってください。このプログラムはリンゴを の「これ」として渡しますがBanana.Peel()、これは明らかに間違っています。

コンパイラはこれが発生する可能性があることを認識しているため、最初にインターフェイスを宣言することを許可しません。


分散についてさらに質問がある場合はどうすればよいですか?

この機能の設計と実装に関する私の記事を読むことから始めてください。下から始めます。それらは逆の時系列順にリストされています。

http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/

それでも質問がある場合は、質問が実際に何であるかを人々に推測させるのではなく、実際に質問を含む質問をここに投稿する必要があります。

于 2013-01-10T18:07:08.820 に答える