C#での共変性と反変性を使用するIList、これは可能ですか?
-
12-09-2019 - |
質問
これは可能でしょうか? (私は対2010を持っていないので、私はそれを自分自身を試すことはできません、申し訳ありません)。
public interface IComplexList<out TOutput, in TInput> where TOutput : TInput
{
public IEnumerator<TOutput> GetEnumerator();
public void Add(TInput item);
}
public interface IList<T> : IComplexList<T, T>
{
}
私は右のそれを取得する場合、あなたが実際に同じインタフェースで共変性と反変性を実装するために、これを使用することができます。
解決
いいえ、あなたがすることはできません。あなたの例ではIList<T>
は不変です。 IList<T>
は共変/反変であることをin
/ out
を宣言するために必要となります。それはちょうど共変であるいくつかのインターフェイスを継承することによってそれを行うことはできません。
他のヒント
さて、あなたの質問は、理由は、既存のIList<T>
タイプで少し混乱しています。ただし、次ののないのコンパイルます:
public interface IComplexList<out TOutput, in TInput> where TOutput : TInput
{
IEnumerator<TOutput> GetEnumerator();
void Add(TInput item);
}
public interface ISimpleList<T> : IComplexList<T, T>
{
}
あなたもIEnumerable<TOutput>
を拡張するためにそれを変更することができます:
public interface IComplexList<out TOutput, in TInput>
: IEnumerable<TOutput>
where TOutput : TInput
{
void Add(TInput item);
}
public interface ISimpleList<T> : IComplexList<T, T>
{
}
あなたはさまざまなタイプが関与したいと思いますので、インデクサは、注意が必要です。あなたが行うことができます:
TOutput Get(int index);
void Set(int index, TInput item);
、その後ISimpleList<T>
にインデクサーを置く代わりに、当然の...
それはあなたが基本的に強制しましたので、あなたは、variantlyしかしISimpleList<T>
を使用できませんTInput = TOutputます。
別のアプローチは、出力から入力を分離することである。
public interface IReadableList<out T> : IEnumerable<T>
{
T Get(int index);
}
public interface IWritableList<in T>
{
void Add(T item);
void Set(int index, T item);
}
public interface IMyList<T> : IReadableList<T>, IWritableList<T> {}
次に、あなたが書くことができます:
public void Foo(IWritableList<string> x) { ... }
IMyList<object> objects = new MyList<object>();
Foo(objects);
とIReadableList
ためその逆。言い換えれば、あなたは個別にそれぞれの側の分散を許可しますが、2つの側面のための分散を取得することはありません。
、一つは(Tの)のIListを持つことにより、リストの共変性と反変性の有用な形態を追加することができます(アウトTの)IReadableListから派生そしてIAddableList(IN Tの)。提供されるインターフェースは、単に、それらが定義される前(T OF)のIListに存在していたメンバーが含まれていること、(Tの)のIListを実装するコードは、自動的にそれらの他のメンバーを実装することになります。 IReadableListは共変であるためには残念ながら、それは読み取り専用のインデクサプロパティを持っている必要があります。 IList内で読み書き可能プロパティの実装を置換することができませんでした。 (Tの)のIListは(アウトTの)使用可能なIReadableListから継承有するので(Tの)のIListのすべての実装を破るます。