Esta pregunta es muy confuso . Déjame ver si puedo aclararlo.
Cuando trato de poner en práctica IGreatInterface
las opciones del compilador de un error de aMethodBeta()
porque he hecho que el método utilizando un subtipo de IAnInterface
Quiero implementar ese método como este: Object aMethodBeta(AnInterestingClass parameter)
.
Eso no es legal. Simplificando un tanto:
class Food {}
class Fruit : Food {}
class Meat : Food {}
interface IEater
{
void Eat(Food food);
}
class Vegetarian : IEater
{
public void Eat(Fruit fruit);
}
Clase Vegetarian
no cumple con el contrato de IEater
. Debería poder pasar cualquier Comida para comer, pero Vegetarian
solo acepta fruta. C# no admite covariación del parámetro formal del método virtual porque no es seguro.
Ahora, se podría decir entonces, ¿qué tal esto:
interface IFruitEater
{
void Eat(Fruit fruit);
}
class Omnivore : IFruitEater
{
public void Eat(Food food);
}
Ahora tenemos la seguridad de tipos; Omnivore
se puede utilizar como IFruitEater
porque un Omnivore
puede comer fruta, así como cualquier otro alimento.
Desafortunadamente, C# no es compatible con método virtual contraviorencia de tipo de parámetro formal aunque hacerlo en teoría es seguro. Pocos idiomas lo admiten.
De forma similar, C# no es compatible con varianza del tipo de retorno del método virtual tampoco.
No estoy seguro de si eso realmente respondió su pregunta o no. ¿Puedes aclarar la pregunta?
ACTUALIZACIÓN:
¿Qué hay de:
interface IEater
{
void Eat<T>(T t) where T : Food;
}
class Vegetarian : IEater
{
// I only want to eat fruit!
public void Eat<Fruit>(Fruit food) { }
}
No, eso no es legal tampoco. El contrato de IEater
es que proporcionará un método Eat<T>
que puede tomar cualquier T
que es Food
.Puede no parcialmente la ejecución del contrato, más de lo que usted puede hacer esto:
interface IAdder
{
int Add(int x, int y);
}
class Adder : IAdder
{
// I only know how to add two!
public int Add(2, int y){ ... }
}
Sin embargo, usted puede hacer esto:
interface IEater<T> where T : Food
{
void Eat(T t);
}
class Vegetarian : IEater<Fruit>
{
public void Eat(Fruit fruit) { }
}
Eso es perfectamente legal. Sin embargo, no se puede hacer:
interface IEater<T> where T : Food
{
void Eat(T t);
}
class Omnivore : IEater<Fruit>
{
public void Eat(Food food) { }
}
porque, de nuevo, C# no soporta método virtual contravarianza parámetro formal o covarianza.
Tenga en cuenta que C# hace apoyo polimorfismo paramétrico de covarianza cuando lo hace, es conocido por ser typesafe. Por ejemplo, esto es legal:
IEnumerable<Fruit> fruit = whatever;
IEnumerable<Food> food = fruit;
Se puede usar una secuencia de fruta como secuencia de alimentos. O bien,
IEnumerable<Fruit> fruitComparer = whatever;
IComparable<Apples> appleComparer = fruitComparer;
Si tiene algo que pueda comparar dos frutas cualquiera, puede comparar dos manzanas cualquiera.
Sin embargo, este tipo de covarianza y contravarianza solo es legal cuando todo lo siguiente es verdadero: (1) la varianza es probadamente segura, (2) el autor de las anotaciones de varianza agregadas que indican el co y contra -varianzas, (3) los diferentes tipos de argumentos involucrados son todos tipos de referencia, (4) el tipo genérico es un delegado o una interfaz.
No entiendo muy bien su pregunta. ¿Puedes publicar el código que implementa IGreatInterface y el error específico del compilador? – phoog
@Juan: Como nota al margen, ayuda marcar sus actualizaciones con una * actualización * o algo así para que veamos qué ha cambiado. –