Bene, la tua domanda è leggermente confusa a causa del tipo esistente IList<T>
. Tuttavia, il seguente fa di compilazione:
public interface IComplexList<out TOutput, in TInput> where TOutput : TInput
{
IEnumerator<TOutput> GetEnumerator();
void Add(TInput item);
}
public interface ISimpleList<T> : IComplexList<T, T>
{
}
si può anche cambiare per estendere 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>
{
}
L'indicizzatore è difficile, perché si vorrebbe diversi tipi coinvolti. Si potrebbe fare:
TOutput Get(int index);
void Set(int index, TInput item);
e poi mettere l'indicizzatore in ISimpleList<T>
invece ovviamente ...
che non consente di utilizzare ISimpleList<T>
variantly però, perché hai praticamente costretti TInput = tOutput.
Un approccio alternativo è quello di separare l'ingresso dall'uscita:
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> {}
Poi si può scrivere:
public void Foo(IWritableList<string> x) { ... }
IMyList<object> objects = new MyList<object>();
Foo(objects);
e viceversa per IReadableList
. In altre parole, permetti la varianza per ogni lato individualmente, ma non ottieni mai la varianza per i due lati insieme.
Compilare certamente, ma non sarebbe co/contro-variante. 'ISimpleList' non può essere usato come 'ISimpleList
Grazie per aver provato –
aggiornerò la mia risposta per essere più specifica - mi dispiace, continuo a pensare a tutto questo. –