تعریف مفهوم Delegate در #C
برای درک بهتر مفهوم Delegate، تصمیم گرفتیم آموزش مربوط به این درس را از دوره جامع آموزش سیشارپ (مقدماتی) کنارتیم در اختیار شما قرار دهیم.
در ابتدا باید بدونید که Delegate یا به فارسی میشه گفت نماینده، یک نوع دادهای یا type به حساب میآید.
این نوعداده، یک ارجاع به Method رو در خودش ذخیره میکنه.
جملهی بالا گُنگ و سخت بود ولی به زبان ساده، هر نمونه از Delegate یه ظرف برای ذخیرهسازی آدرس یک متد است.
مثال پایهای از Delegate در سیشارپ
اجازه بدید مثال بزنم.
فرض کنید ما یک method داریم به نام Sum برای جمع دو عدد:
static double Sum(double x, double y)
{
return x + y;
}
ورودی این متد ۲ عدد (x, y) از نوع double و خروجی، حاصل جمع این دو عدد است.
حالا من یک Delegate تعریف میکنم که ورودیها و خروجی یکسان با متد Sum داشتهباشه:
public delegate double Calculate(double x, double y);
من این Delegate رو به عنوان یک الگو تعریف کردم. حالا یک نمونه از این الگو میسازم:
Calculate calculate;
حالا فقط کافیه تا به این نمونه (calculate) بگم از این به بعد به Sum اشاره کنه و آدرس Sum رو در خودش داشتهباشه:
calculate = new Calculate(Sum);
از الان به بعد هر وقت calculate رو صدا بزنم، انگار Sum رو صدا زدم:
double d = calculate(2, 3);
کدهای کامل برنامه هم اینجوری میشه:
namespace ConsoleApp11
{
internal class Program
{
public delegate double Calculate(double x, double y);
static double Sum(double x, double y)
{
return x + y;
}
static void Main(string[] args)
{
Calculate calculate;
calculate = new Calculate(Sum);
double d = calculate(2, 3);
Console.WriteLine(d); // 5
}
}
}
برای این که بیشتر از Delegate ببینید و مطمئن بشم که کامل متوجه شدید، این مثال رو یکم جلو میبرم.
در مرحله بعد، من یک Method برای ضرب کردن هم به پروژه اضافه میکنم:
static double Multiply(double x, double y)
{
return x * y;
}
و در ادامه پروژه رو به این صورت تغییر میدم:
namespace ConsoleApp11
{
internal class Program
{
public delegate double Calculate(double x, double y);
static double Sum(double x, double y)
{
return x + y;
}
static double Multiply(double x, double y)
{
return x * y;
}
static void Main(string[] args)
{
Calculate calculate;
calculate = new Calculate(Sum);
double d = calculate(2, 3);
Console.WriteLine(d); // 5
calculate = new Calculate(Multiply);
d = calculate(2, 3);
Console.WriteLine(d); // 6
}
}
}
همونطور که میبینید در ابتدا calculate رو با متد Sum برابر قرار دادم و عملیات جمع رو انجام میده. با ورودی ۲ و ۳ مقدار ۵ چاپ میشه، ولی بعد calculate رو با متد ضرب (Multiply) مقدار دهی کردم و وقتی دوباره calculate رو با اعداد ۲و ۳ فراخوانی کردم، مقدار ۶ رو خروجی گرفتم.
پس شما میتونید متدهای مختلفی با الگوی یکسان داشته باشید که کارهای مختلفی انجام میدن و با ساخت یک نمونه از Delegate این امکان رو دارید که هر زمان خواستید، نمونه شما کار هر کدام از متدها رو انجام بده.
و اما نکتهی آخر هم این که شما میتونید به جای این عبارت:
calculate = new Calculate(Sum);
مستقیم calculate رو برابر با نام متد قرار بدید و در نتیجه تفاوتی ندارد:
calculate = Sum;
کاربرد Delegate در برنامهنوسی با #C
Delegate تو دنیای واقعی برنامهنویسی به چه کار میاد؟
دقت کردید که شما از متغییرها چطور استفاده میکنید؟ مثلا یک متغییر برای ذخیرهسازی تعداد دانشجوهای یک آموزشگاه تعریف میکنید و انتظار دارید که بعد داخل برنامه تعداد دانشجوها رو از کاربر بپرسیم و یا از پایگاهدادهها استخراج کنیم. در واقع ما میدونیم که تعداد دانشجوهایی رو داریم اما این تعداد از قبل مشخص نیست. پس ما یک متغییر میسازیم تا بعدتر مقدار بگیره.
Delegate هم به همین صورت به کار میاد. ما یک متغییر میسازیم ولی اینبار برای ذخیره سازی یک متد. چرا؟ چون میدونیم که باید چنین متدی وجود داشته باشه و فراخوانی بشه اما این که داخل این متد چی باشه الان مشخص نیست.
سناریو بسازیم؟
فرض کنید شما در حال توسعه یک ساختار امنیتی برای وبسایتها هستید. کدهای شما به این شکل کار میکنند که حملات هکرها رو پیدا و دفع میکنند. شما این کدها رو به صورت package در میارید و در اختیار همهی توسعه دهندگان وب قرار میدید.
در زمان نوشتن این کدها شما اگر چه میدونید که چطور حملات رو تشخیص بدید و دفع کنید ولی آیا میدونید توسعهدهندگان وبسایتها چطور دوستدارند با موضوع حمله برخورد کنند؟
من برای وبسایت خودم ترجیح میدم که پیامی روی صفحه نمایش داده بشه که ما متوجه شدیم که شما تلاش میکردید وبسایت ما رو هک کنید ولی ما این حمله رو دفع کردیم.
گروه دیگری که در حال استفاده از کدهای شما هستند دوستدارند در صورت حمله بلافاصله به مدیران وبسایت، پیامک هشدار ارسال شود تا بررسیهای بیشتر در این باره انجام شود.
پس شما در زمان نوشتن کد آگاه هستید که در صورت دفع حمله، توسعهدهندگان وبسایت، رویکردهای متفاوتی اتخاذ میکند که شما از آنها آگاه نیستید.
نتیجهگیری
- Delegate میسازید که ورودی و خروجی مشخص دارد.
- یک نمونه از این Delegate ایجاد میکنید.
- زمانی که حمله دفع شد این نمونه را فراخوانی میکنید. درست مثل حالتی که ما متد Calculate رو فراخوانی کردیم.
حالا توسعهدهندگان میتوانند هر فرآیندی که مورد نظر است را بنویسند و مثل متد Sum در مثال ما به نمونهی Delegate شما نسبت بدهند. تا زمانی که شما فراخوانی را انجام میدهید این متدها اجرا شوند.
ویدئو آموزشی Delegate که مربوط به دورهي مقدماتی #C است رو هم حتماً ببینید و اگر نظر یا سوالی داشتید، زیر همین پست برای ما بنویسید.