2011-10-20 39 views
7

Tôi có một chương trình mẫu với lớp cơ sở Fruit và lớp học có nguồn gốc Apple.Làm thế nào để thêm một đại biểu táo vào một danh sách các đại biểu hoa quả?

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

Tôi muốn có danh sách các đại biểu hoa quả và có thể thêm đại biểu của nhiều trái cây có nguồn gốc vào danh sách. Tôi tin rằng điều này có liên quan đến hiệp ước hiệp phương hoặc đối nghịch nhưng tôi không thể hình dung ra điều đó.

Thông điệp lỗi là (không gian tên):

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

Trả lời

4

Một FruitDelegate <Fruit> là một đại biểu chấp nhận bất kỳ trái cây. Ví dụ, sau đây là hợp lệ:

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

Bạn có thể làm cho các tham số kiểu T của FruitDelegate <T>contravariant:

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

cho phép bạn gán một FruitDelegate <Fruit> bản sao cho FruitDelegate <Apple> biến:

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

Điều này là hợp lệ, vì đại biểu đề cập đến một phương pháp (trong số các loại trái cây khác) chấp nhận táo.

Tuy nhiên, bạn không thể gán một FruitDelegate < của Apple > dụ đến một FruitDelegate <Fruit> biến:

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

này không hợp lệ, vì các đại biểu nên chấp nhận bất kỳ trái cây, nhưng sẽ tham khảo một phương pháp không chấp nhận trái cây nào khác ngoài quả táo.

Kết luận: bạn không thể thêm một FruitDelegate < của Apple > dụ vào một danh sách < FruitDelegate <Fruit> >, bởi vì một FruitDelegate < của Apple > không phải là một FruitDelegate <Fruit>.

Các vấn đề liên quan