Console.WriteLine("Xob: " + Xob.Val);

// В этом случае возвращаемым типом метода IncrB служит объект класса Y, // а возвращаемым типом делегата Changelt — объект класса X. Но благодаря // ковариантности следующая строка кода оказывается вполне допустимой, change = IncrB;

Yob = (Y) change(Yob);

Console.WriteLine("Yob: " + Yob.Val);

}

}

Вот к какому результату приводит выполнение этого кода.

Xob: 1 Yob: 1

В данном примере классYявляется производным от классаX.А делегатChangeltобъявляется следующим образом.

delegate X Changelt(Y obj);

Делегат возвращает объект классаXи принимает в качестве параметра объект классаY.А методыIncrA() иIncrB() объявляются следующим образом.

static X IncrA(X obj) static Y IncrB(Y obj)

МетодIncrA() принимает объект классаXв качестве параметра и возвращает объект того же класса. А методIncrB() принимает в качестве параметра объект классаYи возвращает объект того же класса. Но благодаря ковариантности и контравари-антности любой из этих методов может быть передан делегатуChangelt,что и демонстрирует рассматриваемый здесь пример.

Таким образом, в строке

Changelt change = IncrA;

методIncrA() может быть передан делегату благодаря контравариантности, так как объект классаXслужит в качестве параметра методаIncrA (), а объект классаY —в качестве параметра делегатаChangelt.Но метод и делегат оказываются совместимыми в силу контравариантности, поскольку типом параметра метода, передаваемого делегату, служит класс, являющийся базовым для класса, указываемого в качестве типа параметра делегата.

Приведенная ниже строка кода также является вполне допустимой, но на этот раз благодаря ковариантности.

change = IncrB;

В данном случае возвращаемым типом для методаIncrB() служит классY,а для делегата — класс X. Но поскольку возвращаемый тип метода является производным классом от возвращаемого типа делегата, то оба оказываются совместимыми в силу ковариантности.

Класс System. Delegate

Все делегаты и классы оказываются производными неявным образом от классаSystem. Delegate.Как правило, членами этого класса не пользуются непосредственно, и этоНеделается явным образом в данной книге. Но члены классаSystem. Delegateмогут оказаться полезными в ряде особых случаев.

Назначение делегатов

Перейти на страницу:

Похожие книги