Net framework 5, а также среды Visual Studio 2012 и C#



Download 6,27 Mb.
Pdf ko'rish
bet325/658
Sana12.06.2023
Hajmi6,27 Mb.
#950840
1   ...   321   322   323   324   325   326   327   328   ...   658
Bog'liq
CLR via C Programmirovanie na platforme Microsoft NET Framework 4 5 na yazyke C

рис. 17.5.
.Делегаты.после.вставки.в.цепочку.второго.члена
Для добавления в цепочку третьего делегата снова вызывается метод 
Combine
:
fbChain = (Feedback) Delegate.Combine(fbChain, fb3);
И снова, видя, что переменная 
fbChain
уже ссылается на делегата, метод соз-
дает очередного делегата, как показано на рис. 17.6. Как и в предыдущих случаях
новый делегат присваивает начальные значения своим закрытым полям 
_target
и 
_methodPtr
, в то время как поле 
_invocationList
инициализируется ссылкой на 
массив делегатов. Первому и второму элементам массива (с индексами 0 и 1) при-
сваиваются ссылки на те же делегаты, на которые ссылался предыдущий делегат. 
Третий элемент массива (с индексом 2) становится ссылкой на делегата, служащего 


446
Глава.17 .Делегаты
оболочкой метода 
FeedbackToFile
(именно на этого делегата ссылается переменная 
fb3
). Наконец, переменной 
fbChain
присваивается ссылка на вновь созданного 
делегата. При этом ранее созданный делегат и массив, на который ссылается его 
поле 
_invocationList
, теперь подлежат обработке механизмом уборки мусора.
рис. 17.6.
.Окончательный.вид.цепочки.делегатов
После выполнения кода, создающего цепочку, переменная 
fbChain
передается 
методу 
Counter
:
Counter(1, 2, fbChain);
Метод 
Counter
содержит код неявного вызова метода 
Invoke
для делегата 
Feedback
. Впрочем, об этом мы уже говорили. Когда метод 
Invoke
вызывается для 
делегата, ссылающегося на переменную 
fbChain
, этот делегат обнаруживает, что 
значение поля 
_invocationList
отлично от 
null
. Это приводит к выполнению 
цикла, перебирающего все элементы массива, вызывая для них метод, оболочкой 
которого служит указанный делегат. В нашем примере методы вызываются в сле-
дующей последовательности: 
FeedbackToConsole

FeedbackToMsgBox
и, наконец, 
FeedbackToFile
.
Реализация метода 
Invoke
класса 
Feedback
выглядит примерно так (в псевдо-
коде):


447
Обратный.вызов.нескольких.методов.(цепочки.делегатов)
public void Invoke(Int32 value) {
Delegate[] delegateSet = _invocationList as Delegate[];
if (delegateSet != null) {
// Этот массив указывает на делегаты, которые следует вызвать
foreach (Feedback d in delegateSet)
d(value); // Вызов каждого делегата
} else {
// Этот делегат определяет используемый метод обратного вызова.
// Этот метод вызывается для указанного объекта.
_methodPtr.Invoke(_target, value);
// Строка выше — имитация реального кода.
// То, что происходит в действительности, не выражается средствами C#.
}
}
Для удаления делегатов из цепочки применяется статический метод 
Re move
объекта 
Delegate
. Эта процедура демонстрируется в конце кода метода 
Chain-
DelegateDemo1
:
fbChain = (Feedback) Delegate.Remove(
fbChain, new Feedback(FeedbackToMsgBox));
Метод 
Remove
сканирует массив делегатов (с конца и до члена с нулевым индек-
сом), управляемый делегатом, на который ссылается первый параметр (в нашем 
примере это 
fbChain
). Он ищет делегат, поля 
_target
и 
_methodPtr
которого совпа-
дают с соответствующими полями второго аргумента (в нашем примере это новый 
делегат 
Feedback
). При обнаружении совпадения, если в массиве осталось более 
одного элемента, создается новый делегат — создается массив 
_invocationList

который инициализируется ссылкой на все элементы исходного массива за ис-
ключением удаляемого, — после чего возвращается ссылка на нового делегата. При 
удалении последнего элемента цепочки метод 
Remove
возвращает значение 
null

Следует помнить, что метод 
Remove
за один раз удаляет лишь одного делегата, а не 
все элементы с указанными значениями полей 
_target
и 
_methodPtr
.
Ранее мы также рассматривали делегат 
Feedback
, возвращающий значение типа 
void
. Однако этот делегат можно было определить и так:
public delegate Int32 Feedback(Int32 value);
В этом случае псевдокод метода 
Invoke
выглядел бы следующим образом:
public Int32 Invoke(Int32 value) {
Int32 result;
Delegate[] delegateSet = _invocationList as Delegate[];
if (delegateSet != null) {
// Массив указывает на делегаты, которые нужно вызвать
foreach (Feedback d in delegateSet)
result = d(value); // Вызов делегата
} else {
// Этот делегат определяет используемый метод обратного вызова.
// Этот метод вызывается для указанного объекта.
result = _methodPtr.Invoke(_target, value);
продолжение



448
Download 6,27 Mb.

Do'stlaringiz bilan baham:
1   ...   321   322   323   324   325   326   327   328   ...   658




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish