مفهوم دلیگیت (Delegate) در سیشارپ به زبانی ساده :
با درود امروز میخواهیم با یه مفهوم کاربردی در سیشارپ آشنا بشیم که اسمش دلیگیت (Delegate) هست. فکر کنید دلیگیت مثل یه "پیک موتوری" توی دنیای برنامهنویسیه که کارش اینه که تابع رو براتون ببره و هرجا که گفتید تحویل بده! این پیک موتوری فقط همون کاری رو انجام میده که شما بهش سفارش دادید، نه بیشتر و نه کمتر. بیاید این مفهوم رو با یه داستان یاد بگیریم.
تصور کنید توی یه رستوران کار میکنید. مشتریها سفارش غذا میدن (مثلاً کباب یا پیتزا)، اما شما بهعنوان آشپز نمیتونید خودتون غذا رو ببرید سر میز. اینجا دلیگیت وارد میشه! دلیگیت مثل گارسون رستوران عمل میکنه: شما بهش میگید "این تابع پخت کباب رو بگیر و هر وقت مشتری صداش کرد، براش اجرا کن". حالا هر مشتری که سفارش کباب بده، دلیگیت میدونه باید کدوم تابع رو صدا بزنه. این یعنی دلیگیت یه جور "واسطه" بین سفارشدهنده (رویداد) و اجراکننده (تابع) می باشد.
از نظر فنی، دلیگیت یه نوع داده (Type) خاص تو سیشارپه که میتونه به یه تابع اشاره کنه. مثل یه اشارهگر (Pointer) عمل میکنه، ولی خیلی امنتر و شیکتره. شما اول دلیگیت رو تعریف میکنید و میگید که چه شکلی تابعها رو قبول میکنه (مثلاً ورودی و خروجی تابع چی باشه)، بعد هر تابعی که این شکل رو داشته باشه میتونه به دلیگیت وصل بشه. این قابلیت باعث میشه کدتون انعطافپذیر بشه، چون میتونید تابعها رو مثل لِگو به جاهای مختلف وصل کنید و جدا کنید!
به مثال رستوران برمی گردیم فرض کنید توی رستوران دو نوع غذا داریم: کباب و پیتزا. میخواهیم یه دلیگیت بسازیم که سفارش مشتری رو به آشپز برسونه:
using System;
class Program
{
// تعریف دلیگیت: یه پیک موتوری که فقط اسم غذا رو میبره و تحویل میده
delegate void FoodOrder(string foodName);
static void Main(string[] args)
{
// ساختن یه دلیگیت به اسم waiter (گارسون)
FoodOrder waiter;
// وصل کردن دلیگیت به تابع پخت کباب
waiter = CookKebab;
Console.WriteLine("سفارش مشتری اول:");
waiter("کباب کوبیده"); // گارسون میره کباب رو سفارش میده
// حالا وصل کردن دلیگیت به تابع پخت پیتزا
waiter = CookPizza;
Console.WriteLine("سفارش مشتری دوم:");
waiter("پیتزا مارگاریتا"); // گارسون حالا پیتزا رو سفارش میده
// میتونیم چند تابع رو با هم وصل کنیم (Multicast)
waiter = CookKebab;
waiter += CookPizza; // گارسون حالا دوتا کار رو با هم انجام میده
Console.WriteLine("سفارش مشتری سوم:");
waiter("کباب و پیتزا با هم!");
}
// تابع پخت کباب
static void CookKebab(string foodName)
{
Console.WriteLine($"آشپز داره {foodName} رو آماده میکنه. صبر کن داغ و تازه برسه!");
}
// تابع پخت پیتزا
static void CookPizza(string foodName)
{
Console.WriteLine($"آشپز داره {foodName} رو توی فر میذاره. بوی خوبش داره میاد!");
}
}
خروجی این کد:
سفارش مشتری اول:
آشپز داره کباب کوبیده رو آماده میکنه. صبر کن داغ و تازه برسه!
سفارش مشتری دوم:
آشپز داره پیتزا مارگاریتا رو توی فر میذاره. بوی خوبش داره میاد!
سفارش مشتری سوم:
آشپز داره کباب و پیتزا با هم! رو آماده میکنه. صبر کن داغ و تازه برسه!
آشپز داره کباب و پیتزا با هم! رو توی فر میذاره. بوی خوبش داره میاد!
delegate
همان طور که می دانید یک متد می تواند چندین پارامتر با نوع های مختلف را یکجا دریافت نماید.مانند عدد صحیح ، اعشاری و یا رشته اما تا کنون به این فکر کرده اید که آیا می شود یک متد را بعنوان پارامتری به متد دیگر تحویل داد .
اگر قصد چنین کاری را دارید ، متدی را که می خواهید بعنوان پارامتر باشد بایستی بصورت delegate تعریف کنید .
برنامه زیر نمونه ای از کاربرد دلیگیت می باشد .
using System;
namespace deligayt
{
class Program
{
public delegate void Print(int value);
static void Main(string[] args)
{
// Print delegate points to PrintNumber
Print printDel = PrintNumber;
printDel(100000);
printDel(200);
// Print delegate points to PrintMoney
printDel = PrintMoney;
printDel(10000);
printDel(200);
Console.ReadLine();
}
public static void PrintNumber(int num)
{
Console.WriteLine("Number: {0,-12:N0}", num);
}
public static void PrintMoney(int money)
{
Console.WriteLine("Money: {0:C}", money);
} } }
یک نمونه برنامه دیگر از نحوه استفاده از دلیگیت :
using System;
delegate int NumberChanger(int n);
namespace DelegateAppl {
class TestDelegate {
static int num = 10;
public static int AddNum(int p) {
num += p;
return num;
}
public static int MultNum(int q) {
num *= q;
return num;
}
public static int getNum() {
return num;
}
static void Main(string[] args) {
//create delegate instances
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
//calling the methods using the delegate objects
nc1(25);
Console.WriteLine("Value of Num: {0}", getNum());
nc2(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey(); } } }
خروجی برنامه بالا بصورت زیر می باشد . - - - - -
Value of Num: 35 Value of Num: 175