Domanda

questo sarebbe possibile? (Non ho rispetto al 2010, quindi non posso provare io stesso, mi dispiace)

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>
{
}

Se ho capito bene, si potrebbe usare questo per implementare effettivamente covarianza e controvarianza nella stessa interfaccia.

È stato utile?

Soluzione

No, non puoi. Nel tuo esempio IList<T> è invariante. IList<T> richiederebbe di dichiarare in / out essere covariante / contravariant. Non è possibile farlo solo ereditando alcune interfaccia che è covariante.

Altri suggerimenti

Bene, la tua domanda è un po 'confusa a causa del tipo IList<T> esistente. Tuttavia, i seguenti fa 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 di 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 potrebbe scrivere:

public void Foo(IWritableList<string> x) { ... }

IMyList<object> objects = new MyList<object>();
Foo(objects);

e viceversa per IReadableList. In altre parole, si consente varianza per ogni lato singolarmente, ma non si ha mai varianza per le due parti insieme.

Se l'implementazione di una proprietà di lettura e scrittura sono stati considerati anche l'implementazione di una proprietà di sola lettura, si potrebbe aggiungere una forma utile di Lista covarianza e controvarianza avendo IList (T) derivano da IReadableList (di Out T) e IAddableList (di In T). Purché tali interfacce incluse semplicemente membri che erano presenti in IList (Of T) prima che fossero definiti, codice che implementato IList (Of T) attuerebbe automaticamente tali altri membri. Purtroppo, per IReadableList essere covariante, avrebbe dovuto avere una proprietà indicizzatore di sola lettura; l'attuazione della proprietà di lettura-scrittura in IList non può essere sostituita. Avendo IList (Of T) eredita da un IReadableList utilizzabile (di Out T) sarebbe quindi rompere tutte le implementazioni di IList (Of T).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top