Делегатқа әдістерді қосу Жоғарыдағы мысалдарда делегаттың айнымалысы бір әдісті көрсетті. Шындығында, делегат бірдей қолтаңбасы бар және қайтарылатын типі бар көптеген әдістерді көрсете алады. Делегаттағы барлық әдістер арнайы тізімге енеді - шақыру тізімі немесе invocation list. Делегат шақырылған кезде осы тізімдегі барлық әдістер дәйекті түрде шақырылады. Біз бұл тізімге бір емес, бірнеше әдісті қоса аламыз. Делегатқа әдістерді қосу үшін + = операциясы қолданылады:
1
2
3
4
5
6
7
8
Message message = Hello;
message += HowAreYou; // енді message екі әдісті көрсетеді
message(); // екі әдісте шақырылады - Hello және HowAreYou
void Hello() => Console.WriteLine("Hello");
void HowAreYou() => Console.WriteLine("How are you?");
delegate void Message();
Бұл жағдайда message делегатының шақыру тізіміне екі әдіс қосылады - Hello және How Are You. Message шақырылған кезде осы әдістердің екеуі де бірден шақырылады.
Алайда, іс жүзінде делегаттың ескі көшірмесінің әдістерін және жаңа әдісті алатын жаңа делегат объектісі құрылатынын және жаңа құрылған делегат объектісі message айнымалысына тағайындалатынын атап өткен жөн.
Делегаттарды қосқанда, біз бір әдіске сілтемені бірнеше рет қоса алатынымызды ескеру керек, содан кейін делегаттың шақыру тізімінде бір әдіске бірнеше сілтемелер болады. Тиісінше, делегат шақырылған кезде, қосылған әдіс қанша рет қосылса, сонша рет шақырылады:
Консольды шығару:
Hello
How are you?
Hello
Hello
Сол сияқты біз операцияларды қолдана отырып, делегаттан әдістерді алып тастай аламыз -=:
1
2
3
4
5
Message? message = Hello;
message += HowAreYou;
message(); // message-ден барлық әдістер шақырылады
message -= HowAreYou; // HowAreYou әдісін жоямыз
if (message != null) message(); // Hello әдісі шақырылады
Әдістерді делегаттан алып тастаған кезде іс жүзінде жаңа делегат құрылады, ол әдістерді шақыру тізімінде бір әдіске аз болады.
Айта кету керек, әдісті алып тастаған кезде, делегатта әдістер болмайды, содан кейін айнымалы мәні нөлге тең болады. Сондықтан, бұл жағдайда айнымалы тек Message типті айнымалы ретінде емес, Message ретінде анықталады?, яғни Message делегаты да, null мәні де болуы мүмкін типі.
Сонымен қатар, екінші шақыру алдында айнымалыны null мәніне тексереміз.
Жою кезінде, егер делегатта бір әдіске бірнеше сілтемелер болса, онда -= операциясы делегаттың шақыру тізімінің соңынан іздеуді бастайды және тек табылған бірінші кездесуді жояды. Егер делегаттың шақыру тізімінде мұндай әдіс болмаса, онда -= операциясы ешқандай әсер етпейді.