delegate void Message();0
Xabar delegati bekor turini qaytaradi (ya'ni hech narsani qaytarmaydi) va hech qanday parametrlarni olmaydi. Bu shuni anglatadiki, bu delegat hech qanday parametrlarni qabul qilmaydigan va hech narsa qaytarmaydigan har qanday usulga ishora qilishi mumkin.
Ushbu delegatdan foydalanishni ko'rib chiqing:
1
2
3
4
5
6
7
|
Message mes; // 2. Delegat o'zgaruvchisini yarating
mes = Salom Dasturchi!; // 3. Ushbu o'zgaruvchiga usulning manzilini belgilang
mes(); // 4. Biz usulni chaqiramiz
void Salom Dasturchi!() => Console.WriteLine("Salom Dasturchi!"); delegate void Message(); // 1. Delegat e'lon qiling
|
Avvalo, delegatning o'zini aniqlashingiz kerak:
1
|
delegate void Message(); // 1. Delegatni kiritish
|
Delegatdan foydalanish uchun ushbu delegatning o'zgaruvchisi e'lon qilinadi:
1
|
Message mes; // 2. Delegat o'zgaruvchisini yarating
|
Keyinchalik, ma'lum bir usulning manzili (bizning holatda, Salom usuli) delegatga uzatiladi. E'tibor bering, bu usul delegat bilan bir xil qaytish turiga va bir xil parametrlar to'plamiga ega (bu holda hech qanday parametr yo'q).
1
|
mes = Salom Dasturchi!; // 3. Ushbu o'zgaruvchiga usulning manzilini
belgilang
|
Keyin, delegat orqali biz ushbu delegat murojaat qiladigan usulni chaqiramiz:
1
|
mes(); // 4. Biz usulni chaqiramiz
|
Delegatni chaqirish usulni chaqirishga o'xshaydi. Biroq, delegatlar ixtiyoriy ravishda faqat delegat o'zgaruvchisi aniqlangan bir sinfda aniqlangan usullarga ishora qilishi mumkin. Bu boshqa sinflar va tuzilmalarning usullari ham bo'lishi mumkin.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
Message message1 = Welcome.Print;
Message message2 = new Salom Dasturchi!().Display;
message1(); // Welcome message2(); // Привет
delegate void Message(); class Welcome
{
public static void Print() => Console.WriteLine("Assalomu alaykum!");
}
class Salom Dasturchi!
{
public void Display() => Console.WriteLine("Salom!");
}
|
Delegatsiyani aniqlash joyi. Agar biz yuqori darajadagi dasturda delegatni aniqlasak, bu C# 10 dan boshlab standart Program.cs fayli, yuqoridagi misolda bo'lgani kabi, u holda, boshqa turlar kabi, delegat kod oxirida aniqlanadi. Lekin printsipial jihatdan delegat sinf ichida aniqlanishi mumkin:
1
2
3
4
5
6
7
|
class Program
{
delegate void Message(); // 1. Delegat e'lon qiling static void Main()
{
Message mes; // 2. Delegat o'zgaruvchisini yarating mes = Salom Dasturchi!; // 3. Ushbu o'zgaruvchiga usulning
|
8
9
10
10
12
|
manzilini belgilang
mes(); // 4. Biz usulni chaqiramiz
void Salom Dasturchi!() => Console.WriteLine("Salom Dasturchi!");
}
}
|
|
Yoki sinfdan tashqarida:
1
2
3
4
5
6
7
8
9
10
11
12
|
delegate void Message(); // 1. Delegat e'lon qilish
{
static void Main()
{
Message mes; // 2. Delegat o'zgaruvchisini yarating mes = Salom Dasturchi!; // 3. Ushbu o'zgaruvchiga usulning
manzilini belgilang
mes(); // 4. Biz usulni chaqiramiz
void Salom Dasturchi!() => Console.WriteLine("Salom Dasturchi!");
}
}
|
Delegatsiya parametrlari va natijasi. Parametrlarni oladigan va natijani qaytaradigan delegatni aniqlash va undan foydalanishni ko'rib chiqing:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Operation operation = Add; // delegat usulga ishora qiladi int result = operation(4, 5);
Console.WriteLine(result);
operation = Multiply; // endi delegat Mutiply usulga ishora qiladi result = operation(4, 5);
Console.WriteLine(result); int Add(int x, int y) => x + y;
int Multiply(int x, int y) => x * y;
delegate int Operation(int x, int y);
|
Bunday holda, Operatsiya vakili int qiymatini qaytaradi va ikkita int parametriga ega. Shuning uchun bu delegat int qiymatini qaytaradigan va ikkita int parametrini oladigan har qanday usulga mos keladi. Bunday holda, bular Qo'shish va Ko'paytirish usullari. Ya'ni, biz ushbu usullardan istalganini delegat o'zgaruvchisiga belgilashimiz va qo'ng'iroq qilishimiz mumkin. Delegat int tipidagi ikkita parametrni olganligi sababli, siz uni chaqirganingizda, ushbu parametrlar uchun qiymatlarni o'tkazishingiz kerak: operation(4,5). Usul ma'lumotnomasini tayinlash. Yuqorida delegat o'zgaruvchisi to'g'ridan-to'g'ri usulga tayinlangan. Boshqa usul ham bor - konstruktor yordamida delegat ob'ektini yaratish, unga kerakli usul o'tkaziladi:
1
2
3
4
5
6
|
Operation operation1 = Add;
Operation operation2 = new Operation(Add); int Add(int x, int y) => x + y;
delegate int Operation(int x, int y);
|
Ikkala yo'l ham bir xil natija beradi. Delegatga xaritalash usullari. Yuqorida yozilganidek, usullar bir xil qaytish turiga va bir xil parametrlar to'plamiga ega bo'lsa, delegatga mos keladi. Lekin shuni yodda
tutingki, ref , in va out modifikatorlari ham hisobga olinadi . Masalan, bizda delegat bor deylik:
1
|
delegate void SomeDel(int a, double b);
|
Bu delegat, masalan, quyidagi usulga mos keladi:
1
|
void SomeMethod1(int g, double n) { }
|
Va quyidagi usullar mos EMAS:
1
2
3
4
|
double SomeMethod2(int g, double n) { return g + n; } void SomeMethod3(double n, int g) { }
void SomeMethod4(ref int g, double n) { }
void SomeMethod5(out int g, double n) { g = 6; }
|
Bu yerda SomeMethod2 usuli delegat turidan farqli qaytish turiga ega. SomeMethod3 boshqa parametrlar to'plamiga ega. SomeMethod4 va SomeMethod5 parametrlari ham delegat parametrlaridan farq qiladi, chunki ular ref va out modifikatorlariga ega. Delegatga usullar qo'shish. Yuqoridagi misollarda delegat o'zgaruvchisi 1 usulga ishora qildi. Aslida, delegat bir xil imzo va qaytish turiga ega bo'lgan bir nechta usullarni ko'rsatishi mumkin. Delegatdagi barcha usullar maxsus ro'yxatga kiradi - chaqiruv ro'yxati yoki chaqiruv ro'yxati. Va delegat chaqirilganda, ushbu ro'yxatdagi barcha usullar ketma-ket chaqiriladi. Va biz bu ro'yxatga bir emas, balki bir nechta usullarni qo'shishimiz mumkin. += operatori delegatga usullar qo'shish uchun ishlatiladi :
1
2
|
Message message = Salom Dasturchi!;
message += Dasturlashni boshladik; // Endi xabar ikkita usulga
|
|
3
4
5
6
7
8
|
ishora qiladimessage(); // ikkala usul ham o`rinli - Salom Dasturchi! va yaxshimisiz?
void Salom Dasturchi!() => Console.WriteLine("Salom Dasturchi!"); void HowAreYou() => Console.WriteLine("Dasturlashni boshladik ");
delegate void Message();
|
Bunday holda, xabar vakilining chaqiruv ro'yxatiga ikkita usul, Salom Dasturchi! va HowAreYou qo'shiladi. Va xabar chaqirilganda, bu usullarning ikkalasi ham bir vaqtning o'zida chaqiriladi. Ammo shuni ta'kidlash joizki, haqiqatda delegatning eski nusxasi va yangi usulning usullarini oladigan yangi delegat ob'ekti yaratiladi va yangi yaratilgan delegat ob'ekti xabar o'zgaruvchisiga tayinlanadi. Delegatlarni qo'shganda, shuni yodda tutingki, biz bir xil usulga bir necha marta havola qo'shishimiz mumkin, keyin delegatlar chaqiruvi ro'yxatida bir xil usulga bir nechta havolalar bo'ladi. Shunga ko'ra, delegat chaqirilganda, qo'shilgan usul qancha qo'shilgan bo'lsa, shuncha chaqiriladi:
1
2
3
4
5
6
|
Message message = Salom Dasturchi!; message += _;
message += Salom Dasturchi!; message += Salom Dasturchi!;
message();
|
Konsol(qora ekranda)da chiqishi:
Xuddi shunday, biz -= operatsiyalari yordamida delegatdan usullarni olib tashlashimiz mumkin :
1
2
3
4
5
|
Message? message = Salom Dasturchi!; message += _;
message(); message -= _;
if (message != null) message();
|
Delegatdan usullarni olib tashlash haqiqatda usul chaqiruvi ro'yxatida 1 kamroq usulni o'z ichiga olgan yangi delegatni yaratadi.
Shuni ta'kidlash kerakki, usulni o'chirishda delegatda usullar bo'lmasligi va keyin o'zgaruvchining null bo'lishi mumkin bo'lgan vaziyat yuzaga kelishi mumkin. Shuning uchun, bu holda, o'zgaruvchi faqat turdagi o'zgaruvchi sifatida emas Message, balki Message? , bu xabar vakili yoki null qiymatni ifodalashi mumkin bo'lgan tur.
Bundan tashqari, ikkinchi qo'ng'iroqdan oldin biz o'zgaruvchini null uchun tekshiramiz.
Yo'q qilishda shuni yodda tutingki, agar delegatda bir xil usulga bir nechta havolalar bo'lsa, u holda -= operatsiyasi delegatning chaqiruv ro'yxatining oxiridan qidirishni boshlaydi va faqat birinchi topilgan hodisani olib tashlaydi. Agar delegatning chaqiruv ro'yxatida bunday usul bo'lmasa, -= operatsiyasi hech qanday ta'sir qilmaydi. Delegatlarni birlashtirish uchun Delegatlar boshqa delegatlarga birlashtirilishi mumkin. Misol uchun:
|