Разве это не странно, потому что B Расширяет?
У вас есть правильная идея, но в неправильном направлении. Давайте рассмотрим пример, о котором легче рассуждать:
class Animal {}
class Reptile : Animal {}
class Snake : Reptile {}
class Mammal : Animal {}
class Tiger : Mammal {}
class Giraffe : Mammal {}
delegate void D(Mammal m);
static void DoAnimal(Animal a) {}
static void DoMammal(Mammal m) {}
static void DoTiger(Tiger t) {}
D dm = DoMammal;
dm(new Tiger());
Это явно легально. dm должен быть методом, который принимает Млекопитающее, и это так.
D dt = DoTiger;
dt(new Giraffe());
Это явно должно быть незаконным. Вы не можете назначить метод, который берет тигра для делегата, который принимает млекопитающего, потому что делегат, который принимает млекопитающего, может принимать любого млекопитающего, а не только тигра. Если бы это было законно, тогда было бы возможно передать жирафа методу, который берет тигра.
Что относительно этого?
D da = DoAnimal;
da(new Giraffe());
Это прекрасно. da является делегатом метода, который принимает любое млекопитающее. Метод, который принимает любое животное, очевидно, также принимает любого млекопитающего. Вы можете назначить DoAnimal (Animal) делегату D (Mammal), потому что Mammal расширяет Animal. Теперь вы видите, как вы получили направление расширения назад?
типов Возвращаемых с другой стороны, работать так, как вы думаете, что они делают:
delegate Mammal F();
static Animal GetAnimal() {...}
static Mammal GetMammal() {...}
static Tiger GetTiger() {...}
F fm = GetMammal;
Mammal m = fm();
никакой проблемы.
F ft = GetTiger;
Mammal t = ft();
Проблем нет; GetTiger возвращает тигра, поэтому вы можете назначить его делегату, который требует, чтобы его цель возвращала млекопитающего.
F fa = GetAnimal;
Mammal a = fa();
Это нехорошо. GetAnimal может вернуть Snake, и теперь у вас есть переменная, напечатанная как Mammal, которая содержит Snake. Это должно быть незаконным.
Эта функция называется «ковариация и контравариантность преобразований групп членов», и она была введена в C# 2.0. Для получения дополнительной информации по этой теме смотрите мою статью об этом:
http://blogs.msdn.com/b/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx
это бросить ли исключение или не в компиляции? – Elisha
Это не должно вызывать проблемы. Можете ли вы вставить здесь измененный код? Просто знать, как вы его меняете? –
@Mamta Dalal - отредактировал мой вопрос, надеюсь, что это еще раз очистит его. – Kevin