delegate void Message();
Bunday holda, mes3 ob'ekti mes1 va mes2 delegatlarining birligini ifodalaydi. Delegatlarni birlashtirish mes3 delegatining chaqiruv ro'yxati mes1 va mes2 delegatlarining barcha usullarini o'z ichiga olishini anglatadi. Va mes3 delegati chaqirilganda, bu usullarning barchasi bir vaqtning o'zida chaqiriladi. Delegat chaqiruvida Yuqoridagi misollarda delegat oddiy usul kabi chaqirilgan. Agar delegat parametrlarni olgan bo'lsa, u chaqirilganda parametrlar uchun kerakli qiymatlar o'tkazildi:
1
2
3
4
5
6
7
8
9
10
|
Message mes = Salom Dasturchi!;
mes();
Operation op = Add;
int n = op(3, 4);
Console.WriteLine(n);
void Salom Dasturchi!() => Console.WriteLine("Salom Dasturchi!");
int Add(int x, int y) => x + y;
delegate int Operation(int x, int y);
delegate void Message();
|
Delegatni chaqirishning yana bir usuli Invoke() usulidir :
1
2
3
4
5
6
7
8
9
10
11
|
Message mes = Salom Dasturchi!;
mes.Invoke(); // Salom Dasturchi!
Operation op = Add;
int n = op.Invoke(3, 4);
Console.WriteLine(n); // 7
void Salom Dasturchi!() => Console.WriteLine("Salom Dasturchi!");
int Add(int x, int y) => x + y;
delegate int Operation(int x, int y);
delegate void Message();
|
Agar delegat parametrlarni qabul qilsa, ushbu parametrlar uchun qiymatlar Invoke usuliga o'tkaziladi. Shuni yodda tutingki, agar delegat bo'sh bo'lsa, ya'ni uning chaqiruvlar ro'yxatida hech qanday usullarga havolalar bo'lmasa (ya'ni delegat Null bo'lsa), unda bunday delegatni chaqirganda biz istisnoga ega bo'lamiz, masalan , masalan, quyidagi holatda:
1
2
3
4
5
|
Message? mes;
//mes();
Operation? op = Add;
op -= Addint n = op(3, 4
|
Shuning uchun, delegatni chaqirayotganda, uning null emasligini tekshirish har doim yaxshiroqdir. Yoki Invoke usuli va shartli null operatoridan foydalanishingiz mumkin:
1
2
3
4
5
6
|
Message? mes = null;
mes?.Invoke(); // hech qanday xatolik yo'q, delegat shunchaki chaqirilmaydi
Operation? op = Add;
op -= Add; // op delegati bo'sh
int? n = op?.Invoke(3, 4); вызывается, а n = null
|
Agar delegat ba'zi qiymatni qaytarsa, u holda chaqiruv ro'yxatidagi oxirgi usulning qiymati qaytariladi (agar chaqiruv ro'yxatida bir nechta usullar mavjud bo'lsa). Misol uchun:
1
2
3
4
5
6
7
8
9
10
|
Operation op = Subtract;
op += Multiply;
op += Add;
Console.WriteLine(op(7, 2)); // Add(7,2) = 9
int Add(int x, int y) => x + y;
int Subtract(int x, int y) => x - y;
int Multiply(int x, int y) => x * y;
delegate int Operation(int x, int y);
| Umumiy delegatlarda esa Delegatlar, boshqa turlar singari, umumiy bo'lishi mumkin, masalan:
1
2
3
4
5
6
7
8
9
10
11
|
Operation squareOperation = Square;
decimal result1 = squareOperation(5);
Console.WriteLine(result1); // 25
Operation doubleOperation = Double;
int result2 = doubleOperation(5);
Console.WriteLine(result2); // 10
decimal Square(int n) => n * n;
int Double(int n) => n + n;
delegate T Operation(K val);
|
Bu yyerda Operatsion delegati ikki turdagi parametrlar bilan teriladi. T parametri qaytish turini ifodalaydi. K parametri esa delegatga berilgan parametr turini ifodalaydi. Shunday qilib, bu delegat har qanday turdagi parametrni oladigan va istalgan turdagi qiymatni qaytaradigan mos keladigan usulga ega.
Dasturda biz ma'lum bir usul uchun delegat o'zgaruvchilarini belgilashimiz mumkin. Misol uchun, delegat Operation intni qabul qiladigan va o'nlik kasrni qaytaradigan usulga ega.
Delegat Operation bir necha int turini qabul qiladigan va qaytaradigan usulga ega.
Usul parametrlari sifatida delegatlar. Delegatlar usullarning parametrlari ham bo'lishi mumkin. Buning yordamida 1 usul harakatlarni parametr sifatida qabul qilishi mumkin - boshqa usullar. Misol uchun:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
DoOperation(5, 4, Add); // 9
DoOperation(5, 4, Subtract); // 1
DoOperation(5, 4, Multiply); // 20
void DoOperation(int a, int b, Operation op)
{
Console.WriteLine(op(a,b));
}
int Add(int x, int y) => x + y;
int Subtract(int x, int y) => x - y;
int Multiply(int x, int y) => x * y;
delegate int Operation(int x, int y);
|
DoOperation usuli parametr sifatida ikkita raqamni va Operation delegati ko'rinishidagi ba'zi harakatlarni oladi. Usul ichida biz Operatsion delegatini chaqiramiz va unga dastlabki ikkita parametrdan raqamlarni beramiz. DoOperation usulini chaqirganda, Operation delegatiga mos keladigan usulni uchinchi parametr sifatida o'tkazishimiz mumkin. Usuldan delegatlarni qaytarish Shuningdek, delegatlarni usullardan qaytarishingiz mumkin. Ya'ni, metoddan ba'zi harakatni boshqa usul shaklida qaytarishimiz mumkin. Misol uchun:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
Operation operation = SelectOperation(OperationType.Add);
Console.WriteLine(operation(10, 4)); // 14
operation = SelectOperation(OperationType.Subtract);
Console.WriteLine(operation(10, 4)); // 6
operation = SelectOperation(OperationType.Multiply);
Console.WriteLine(operation(10, 4)); // 40
Operation SelectOperation(OperationType opType)
{
switch (opType)
{
case OperationType.Add: return Add;
case OperationType.Subtract: return Subtract;
default: return Multiply;
}
}
int Add(int x, int y) => x + y;
int Subtract(int x, int y) => x - y;
int Multiply(int x, int y) => x * y;
enum OperationType
{
Add, Subtract, Multiply
}
delegate int Operation(int x, int y);
|
Bunday holda, usul SelectOperation()parametr sifatida OperationType tipidagi ro'yxatni oladi. Bu raqam uchta konstantani saqlaydi, ularning har biri ma'lum bir arifmetik amalga mos keladi. Va usulning o'zida, parametr qiymatiga qarab, biz ma'lum bir usulni qaytaramiz. Bundan tashqari, usulning qaytarish turi Operatsiya vakili bo'lganligi sababli, usul ushbu delegatga mos keladigan usulni qaytarishi kerak - bizning holatlarimizda bular Qo'shish, Ayirish, Ko'paytirish usullari. Ya'ni, agar SelectOperation usulining parametri bo'lsa OperationType.Add, u holda ikkita raqamni qo'shishni amalga oshiradigan Add usuli qaytariladi:
1
|
case OperationType.Add: return Add;
|
SelectOperation usulini chaqirganda, biz undan kerakli amalni operatsiya o'zgaruvchisiga olishimiz mumkin:
1
|
Operation operation = SelectOperation(OperationType.Add);
|
Va o'zgaruvchan operatsiya chaqirilganda, SelectOperation-dan olingan usul aslida chaqiriladi:
1
2
|
Operation operation = SelectOperation (OperationType.AddConsole.WriteLine(operation(10, 4)); // 14
|
Lambda ifodalari anonim usullarning soddalashtirilgan ifodasidir. Lambda iboralari qiymatni qaytarishi mumkin bo'lgan va boshqa usullarga parametr sifatida o'tkazilishi mumkin bo'lgan ixcham, ixcham usullarni yaratishga imkon beradi.
Lambda iboralari quyidagi sintaksisga ega: lambda operatorining chap tomonida =>parametrlar roʻyxati, oʻng tomonida esa ushbu parametrlar yordamida ifodalar bloki aniqlanadi:
1
|
(parameter_list) => ifoda
|
Ma'lumotlar turi bo'yicha lambda ifodasi delegatni ifodalaydi. Masalan, oddiy lambda ifodasini aniqlaymiz:
1
2
3
4
5
6
|
Xabar salom = () => Console.WriteLine("Salom");
Salom(); // Salom
Salom(); // Salom
Salom(); // Salom
delegat voidMessage();
|
Bunday holda, salom o'zgaruvchisi Xabar delegatini ifodalaydi - ya'ni hech narsa qaytarmaydigan va hech qanday parametr qabul qilmaydigan ba'zi harakatlar. Lambda ifodasi ushbu o'zgaruvchining qiymati sifatida tayinlangan. Ushbu lambda ifodasi Xabar vakiliga mos kelishi kerak - u ham hech qanday parametrlarni olmaydi, shuning uchun lambda operatorining chap tomonida bo'sh qavslar mavjud. Va lambda operatorining o'ng tomonida bajariladigan ifoda -Console.WriteLine("Hello") Keyin dastur ushbu o'zgaruvchini usul sifatida chaqirishi mumkin. Agar lambda ifodasi bir nechta amallarni o'z ichiga olsa, ular jingalak qavslarga joylashtiriladi:
Do'stlaringiz bilan baham: |