我有一个带有基础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) { }
}

我想要一个水果委托(delegate)人列表,并能够将更多派生水果的委托(delegate)人添加到列表中。我相信这与协方差或协方差有关,但我似乎无法弄清楚。

错误消息是(无 namespace ):
The best overloaded method match for 'List<FruitDelegate<Fruit>>.Add(FruitDelegate<Fruit>)' has some invalid arguments`

最佳答案

FruitDelegate 是接受任何水果的委托(delegate)。例如,以下内容有效:

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

您可以将FruitDelegate 的类型参数T设置为contravariant:
public delegate void FruitDelegate<in T>(T o) where T : Fruit;

它允许您将FruitDelegate 实例分配给FruitDelegate 变量:
FruitDelegate<Apple> f = new FruitDelegate<Fruit>(EatFruit);
f(new Apple());

这是有效的,因为委托(delegate)人引用的是(除了其他水果以外)接受苹果的方法。

但是,不能将FruitDelegate 实例分配给FruitDelegate 变量:
FruitDelegate<Fruit> f = new FruitDelegate<Apple>(EatApple); // invalid
f(new Apple());
f(new Banana());

这是无效的,因为委托(delegate)人应该接受任何水果,但是会引用一个除苹果之外不接受其他任何水果的方法。

结论:您不能将FruitDelegate 实例添加到List >,因为FruitDelegate 不是FruitDelegate 。

10-04 12:06