2011-10-20 12 views
7

Tengo un programa de ejemplo con una clase base Fruit y una clase Apple derivada.¿Cómo agregar un delegado de manzana a una lista de delegados de fruta?

class Testy 
{ 
    public delegate void FruitDelegate<T>(T o) where T : Fruit; 

    private List<FruitDelegate<Fruit>> fruits = new List<FruitDelegate<Fruit>>(); 

    public void Test() 
    { 
     FruitDelegate<Apple> f = new FruitDelegate<Apple>(EatFruit); 

     fruits.Add(f); // Error on this line 
    } 

    public void EatFruit(Fruit apple) { } 
} 

Quiero tener una lista de delegados de frutas y poder agregar delegados de más frutas derivadas a la lista. Creo que esto tiene algo que ver con la covarianza o la contradicción, pero parece que no puedo resolverlo.

mensaje El error es (sin espacios de nombres):

The best overloaded method match for 'List<FruitDelegate<Fruit>>.Add(FruitDelegate<Fruit>)' has some invalid arguments` 

Respuesta

4

A FruitDelegate <Fruit> es un delegado que acepta cualquier fruta. Por ejemplo, lo siguiente es válido:

FruitDelegate<Fruit> f = new FruitDelegate<Fruit>(EatFruit); 
f(new Apple()); 
f(new Banana()); 

Puede hacer que el parámetro de tipo T de FruitDelegate <T>contravariant:

public delegate void FruitDelegate<in T>(T o) where T : Fruit; 

que le permite asignar un FruitDelegate <fruta> instancia a FruitDelegate <Apple> variable:

FruitDelegate<Apple> f = new FruitDelegate<Fruit>(EatFruit); 
f(new Apple()); 

Esto es válido, ya que el delegado se refiere a un método que (entre otras frutas) acepta las manzanas.

Sin embargo, no se puede asignar un FruitDelegate < de Apple > instancia a una FruitDelegate <fruta> variables:

FruitDelegate<Fruit> f = new FruitDelegate<Apple>(EatApple); // invalid 
f(new Apple()); 
f(new Banana()); 

Esto no es válida, ya que el delegado debe aceptar cualquier fruta, pero se referiría a un método que no acepta ninguna fruta que no sean manzanas.

Conclusión: no se puede agregar un FruitDelegate < de Apple > instancia a una lista < FruitDelegate <fruta> >, porque un FruitDelegate < de Apple > no es un FruitDelegate <fruta>.

Cuestiones relacionadas