Pregunta

¿sería posible? (No tengo vs. 2010, así que no puedo probar en mi misma, lo siento)

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

Si lo entiendo bien, usted podría usar esto para aplicar en la práctica covarianza y contravarianza en la misma interfaz.

¿Fue útil?

Solución

No, no se puede. En su ejemplo IList<T> es invariante. IList<T> requeriría declarar in / out ser covariante / contravariante. No es posible hacer eso con sólo heredar alguna de las interfaces que es covariante.

Otros consejos

Bueno, su pregunta es un poco confuso debido al tipo IList<T> existente. Sin embargo, la siguiente hace compilar:

public interface IComplexList<out TOutput, in TInput> where TOutput : TInput
{
    IEnumerator<TOutput> GetEnumerator();
    void Add(TInput item);
}

public interface ISimpleList<T> : IComplexList<T, T>
{
}

Puede incluso cambiarlo para extender 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>
{
}

El indexador es complicado, porque te gustaría diferentes tipos involucrados. Se podría hacer:

TOutput Get(int index);
void Set(int index, TInput item);

y luego poner el indexador en ISimpleList<T> lugar, por supuesto ...

Eso no le permiten usar ISimpleList<T> variantemente embargo, debido a que ha obligado básicamente TInput = TOutput.

Un enfoque alternativo es separar la entrada de la salida:

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

A continuación, se podría escribir:

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

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

y viceversa para IReadableList. En otras palabras, permite que la varianza para cada lado de forma individual, pero nunca se tiene la varianza para las dos partes.

Si una implementación de una propiedad de lectura y escritura también se considera una implementación de una propiedad de sólo lectura, se podría añadir una forma útil de Lista covarianza y contravarianza por tener IList (de T) se derivan de IReadableList (de fuera t) y IAddableList (de un T). Siempre que esas interfaces simplemente se incluyen los miembros que estaban presentes en IList (Of T) antes de que se definieron, código que implementa IList (Of T) implementaría de forma automática los otros miembros. Desafortunadamente, para IReadableList sea covariante, tendría que tener una propiedad indexador de sólo lectura; la aplicación de la propiedad de lectura y escritura en IList no podía ser sustituido. Tener IList (Of T) heredan de una IReadableList utilizable (De fuera t) sería por lo tanto romper todas las implementaciones de IList (Of T).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top