Как добавить яблочного делегата в список фруктовых делегатов? - PullRequest
7 голосов
/ 20 октября 2011

У меня есть пример программы с базовым Fruit классом и производным Apple классом.

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

Я хочу иметь список делегатов фруктов и иметь возможность добавлять делегаты более производныхфрукты в список.Я считаю, что это как-то связано с ковариацией или контравариантностью, но я не могу понять это.

Сообщение об ошибке (без пространств имен):

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

1 Ответ

4 голосов
/ 20 октября 2011

A FruitDelegate - делегат, который принимает любые фрукты. Например, допустимо следующее:

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

Вы можете сделать параметр типа T из FruitDelegate контравариантным :

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

, который позволяет назначить FruitDelegate экземпляр переменной FruitDelegate :

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

Это действительно, потому что делегат относится к методу, который (среди других фруктов) принимает яблоки.

Однако нельзя присвоить FruitDelegate экземпляр переменной FruitDelegate :

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

Это недопустимо, потому что делегат должен принимать любые фрукты, но будет ссылаться на метод, который не принимает никаких фруктов, кроме яблок.

Вывод: вы не можете добавить FruitDelegate экземпляр к Списку > , поскольку FruitDelegate не является a FruitDelegate .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...