Delegate در سی شارپ — نماینده ها

تصویر شاخص Delegate در سی شارپ

Delegate یک شیء است که به یک متد اشاره می‌کند، یا به عبارت دیگر، یک متغیر از نوع مرجع است که می‌تواند مرجع به متدها را نگه دارد. این یک راه را فراهم می‌کند که مشخص می‌کند کدام متد زمانی که یک رویداد فراخوانی می‌شود، باید اجرا گردد.

در این مقاله، ابتدا به تعریف و نحوه استفاده از Delegate در سی شارپ می‌پردازیم، سپس نحوه چندگانه‌سازی «Multicasting» و ویژگی‌های کلیدی آن‌ها را بررسی می‌کنیم. همچنین به مفاهیم پیشرفته‌تر مانند متدهای ناشناس و عبارات لامبدا که از Delegate در سی شارپ بهره می‌برند، اشاره خواهیم کرد. اگر قصد دارید درک بهتری از نحوه استفاده از Delegate در سی شارپ داشته باشید، این مقاله راهنمایی جامع برای شما خواهد بود.

مقدمه

در زبان برنامه‌نویسی #C، نماینده ها «Delegates» یکی از مفاهیم کلیدی برای مدیریت روش‌های بازگشتی «Callback»، رویدادها و برنامه‌نویسی پویا هستند. نماینده ها به عنوان اشاره‌گرهای نوع ایمن به متدها عمل کرده و این امکان را فراهم می‌کنند که یک متد خاص را بدون نیاز به دانستن جزئیات پیاده‌سازی آن، فراخوانی کنیم. این ویژگی در توسعه نرم‌افزارهای مدرن، به ویژه در برنامه‌نویسی رویدادمحور، چندنخی و طراحی الگوهای انعطاف‌پذیر، کاربرد گسترده‌ای دارد.

برای مثال، اگر شما روی یک دکمه در یک فرم (برنامه فرم‌های ویندوزی) کلیک کنید، برنامه یک متد خاص را فراخوانی خواهد کرد. به زبان ساده، این یک نوع است که مرجع‌هایی به متدها با لیست پارامتر خاص و نوع بازگشتی معین را نشان می‌دهد و سپس زمانی که نیاز است، متد را در برنامه برای اجرا فراخوانی می‌کند.

تعریف Delegate در سی شارپ

نوع Delegate می‌تواند با استفاده از کلمه کلیدی delegate تعریف «Declaration» شود. پس از اعلان یک delegate، نمونه delegate به متدهایی که نوع بازگشتی و لیست پارامترهایشان با delegate واسطه تطابق دارد، اشاره کرده و آن‌ها را فراخوانی خواهد کرد.

[modifier] delegate [return_type] [delegate_name] ([parameter_list]);
  • modifier: این اصلاح‌گر مورد نیاز است که دسترسی به delegate را تعریف می‌کند و استفاده از آن اختیاری است.
  • delegate: این کلمه کلیدی است که برای تعریف واسطه استفاده می‌شود.
  • return_type: نوع مقداری است که توسط متدهایی که واسطه فراخوانی خواهد کرد، بازگردانده می‌شود. این می‌تواند void باشد. یک متد باید همان نوع بازگشتی را داشته باشد که واسطه دارد.
  • delegate_name: این نام یا شناسه‌ای است که توسط کاربر برای واسطه تعریف می‌شود.
  • parameter_list: این شامل پارامترهایی است که توسط متد زمانی که از طریق واسطه فراخوانی می‌شود، مورد نیاز هستند.

مثال

// “public” is the modifier
// “int” is return type
// “ProgramStore” is delegate name
// “(int G, int F, int G)” are the parameters
public delegate int ProgramStore(int G, int F, int G);

توجه: یک Delegate تنها یک متدی را فراخوانی خواهد کرد که با امضای آن و نوع بازگشتی‌اش سازگار باشد. یک متد می‌تواند یک متد استاتیک مرتبط با یک کلاس باشد یا یک متد نمونه مرتبط با یک شیء، مهم نیست.

فراخوانی Delegate در سی شارپ

پس از تعریف یک Delegate در سی شارپ، یک شیء Delegate با کمک کلمه کلیدی new ایجاد می‌شود. زمانی که یک delegate ایجاد شد، یک فراخوانی متد به delegate به آن متد منتقل می‌شود. پارامترهایی که توسط فراخوانی‌کننده به delegate منتقل می‌شوند، به متد منتقل می‌شوند و مقدار بازگشتی، در صورت وجود، از متد به فراخوانی‌کننده توسط delegate باز می‌گردد. این فرآیند به نام فراخوانی delegate شناخته می‌شود.

ساختار یا Syntax

[delegate_name]  [instance_name] = new [delegate_name](calling_method_name);

مثال

// Using of Delegates
using System;

class PStore 
{
    // Declaring the delegates
    // Here return type and parameter type should 
    // be same as the return type and parameter type
    // of the two methods
    // "addnum" and "subnum" are two delegate names
    public delegate void addnum(int a, int b);
    public delegate void subnum(int a, int b);

    public void sum(int a, int b)
    {
        Console.WriteLine("(100 + 40) = {0}", a + b);
    }

    public void subtract(int a, int b)
    {
        Console.WriteLine("(100 - 60) = {0}", a - b);
    }

    // Main Method
    public static void Main(String []args)
    {
        // creating object "obj" of class "PStore"
        PStore obj = new PStore();

        // creating object of delegate, name as "del_obj1" 
        // for method "sum" and "del_obj2" for method "subtract" &
        // pass the parameter as the two methods by class object "obj"
        // instantiating the delegates
        addnum del_obj1 = new addnum(obj.sum);
        subnum del_obj2 = new subnum(obj.subtract);

        // pass the values to the methods by delegate object
        del_obj1(100, 40);
        del_obj2(100, 60);

        // These can be written as using
        // "Invoke" method
        // del_obj1.Invoke(100, 40);
        // del_obj2.Invoke(100, 60);
    }
}

خروجی

(۱۰۰ + ۴۰) = 140
(۱۰۰ - ۶۰) = 40

توضیح: در برنامه بالا، دو delegate به نام‌های addnum و subnum وجود دارند. ما شیء obj از کلاس PStore را ایجاد می‌کنیم چون هر دو متد (addnum و subnum) متدهای نمونه هستند. بنابراین برای فراخوانی آن‌ها به یک شیء نیاز داریم. اگر متدها استاتیک باشند، دیگر نیازی به ایجاد شیء کلاس نیست.

چندگانه‌سازی Delegate در سی شارپ

چندگانه‌سازی Delegate در سی شارپ یک گسترش از Delegate معمولی (که گاهی به آن واسطه تک‌کست گفته می‌شود) است. این به کاربر کمک می‌کند تا بیشتر از یک متد را در یک فراخوانی واحد هدف قرار دهد.

تصویری از چندگانه سازی Delegate در سی شارپ

ویژگی های چندگانه‌سازی Delegate

Delegateها ترکیب می‌شوند و وقتی شما یک Delegate را فراخوانی می‌کنید، فهرست کامل متدها فراخوانی می‌شود.

  • تمام متدها در ترتیب اول به اول (FIFO) فراخوانی می‌شوند.
  • از عملگر ‘+’ یا ‘+= ‘ برای اضافه کردن متدها به Delegateها استفاده می‌شود.
  • از عملگر ‘–’ یا ‘–=’ برای حذف متدها از لیست Delegateها استفاده می‌شود.

توجه: به یاد داشته باشید که چندگانه‌سازی واسطه باید نوع بازگشتی Void داشته باشد، در غیر این صورت یک استثنای زمان اجرا رخ خواهد داد. همچنین، در چندگانه‌سازی Delegate، تنها مقدار بازگشتی از آخرین متدی که به چندگانه اضافه شده، باز خواهد گشت. با این حال، دیگر متدها به درستی اجرا خواهند شد.

مثال: برنامه زیر نحوه چندگانه‌سازی نماینده ها (Multicasting Delegates) را در #C نشان می‌دهد. در اینجا، یک Delegate برای دو متد مختلف تنظیم شده است، و هر دو متد در یک فراخوانی اجرا می‌شوند.

// C# program to illustrate the 
// Multicasting of Delegates
using System;

class rectangle {
    
// declaring delegate
public delegate void rectDelegate(double height,
                                  double width);

    // "area" method
    public void area(double height, double width)
    {
        Console.WriteLine("Area is: {0}", (width * height));
    }
 
    // "perimeter" method
    public void perimeter(double height, double width)
    {
        Console.WriteLine("Perimeter is: {0} ", 2 * (width + height));
    }
 
 
// Main Method
public static void Main(String []args)
{
    
    // creating object of class 
    // "rectangle", named as "rect"
    rectangle rect = new rectangle();

    // these two lines are normal calling
    // of that two methods
    // rect.area(6.3, 4.2);
    // rect.perimeter(6.3, 4.2);

    // creating delegate object, name as "rectdele"
    // and pass the method as parameter by 
    // class object "rect"
    rectDelegate rectdele = new rectDelegate(rect.area);
    
    // also can be written as 
    // rectDelegate rectdele = rect.area;

    // call 2nd method "perimeter"
    // Multicasting
    rectdele += rect.perimeter; 

    // pass the values in two method 
    // by using "Invoke" method
    rectdele.Invoke(6.3, 4.2);
    Console.WriteLine();
    
    // call the methods with 
    // different values
    rectdele.Invoke(16.3, 10.3);
}
}

خروجی

Area is: 26.46
Perimeter is: 21 

Area is: 167.89
Perimeter is: 53.2
  • در برنامه بالا، ما از نماینده ها (Delegates) برای فراخوانی چندین متد با یک فراخوانی واحد استفاده کردیم.
  • با استفاده از عملگر += متدهای مختلف را به یک واسطه اضافه کردیم (Multicasting).
  • ترتیب اجرای متدها در چندگانه‌سازی Delegateها FIFO است.
  • این تکنیک در برنامه‌نویسی رویدادمحور (Event-driven Programming) و فراخوانی متدهای مرتبط (Chained Method Calls) بسیار کاربردی است.

نکات مهم درباره Delegate در سی شارپ

  • Delegateها روش خوبی برای کپسوله‌سازی متدها فراهم می‌کنند.
  • Delegateها کلاس کتابخانه‌ای در فضای نام System هستند.
  • این‌ها اشاره‌گرهای نوع ایمن به هر متدی هستند.
  • Delegateها عمدتاً در پیاده‌سازی متدهای بازگشتی (callback) و رویدادها استفاده می‌شوند.
  • Delegateها می‌توانند به هم زنجیر شوند، به طوری که دو یا بیشتر متد می‌توانند در یک رویداد فراخوانی شوند.
  • Delegateها به کلاسی که شیء آن به آن اشاره می‌کند اهمیتی نمی‌دهند.
  • Delegateها می‌توانند برای فراخوانی متدهای ناشناس نیز استفاده شوند.

متدهای ناشناس (C# 2.0) و عبارات لامبدا (C# 3.0) در برخی از زمینه‌ها به نوع‌های واسطه کامپایل می‌شوند. گاهی اوقات، این ویژگی‌ها به طور مشترک به عنوان توابع ناشناس شناخته می‌شوند.

نتیجه‌گیری

Delegate در سی شارپ یکی از مفاهیم کلیدی برای مدیریت و ارجاع به متدها به صورت انعطاف‌پذیر و پویا هستند. آن‌ها امکان برنامه‌نویسی رویدادمحور، فراخوانی متدهای بازگشتی «Callback» و چندگانه‌سازی متدها را فراهم می‌کنند. علاوه بر این، نماینده ها به عنوان پایه‌ای برای متدهای ناشناس و عبارات لامبدا عمل کرده و به توسعه‌دهندگان این امکان را می‌دهند که کدهای خواناتر و ساختاریافته‌تری بنویسند.

با یادگیری نحوه استفاده از نماینده‌ها، برنامه‌نویسان می‌توانند کدهای منعطف‌تر، قابل استفاده مجدد و مقیاس‌پذیرتری بنویسند. درک این مفهوم به ویژه در مدیریت رویدادها، برنامه‌نویسی چندنخی و طراحی الگوهای پیشرفته بسیار ارزشمند است. بنابراین، یادگیری و استفاده صحیح از واسطه‌ها می‌تواند به بهبود کیفیت و عملکرد برنامه‌های C# کمک کند.


سوالات متداول


نماینده (Delegate) در C# چیست؟

Delegate یک اشاره‌گر نوع ایمن به متدها است که به ما اجازه می‌دهد متدها را به‌صورت پویا فراخوانی کنیم. Delegateها معمولاً در مدیریت رویدادها و متدهای بازگشتی (Callback) استفاده می‌شوند.

تفاوت بین Delegate در سی شارپ و اشاره‌گرهای تابع در ++C چیست؟

Delegateها در #C نوع ایمن هستند، به این معنی که فقط به متدهایی با امضای سازگار اشاره می‌کنند. اما در ++C اشاره‌گرهای تابع ایمنی نوعی ندارند و می‌توانند به هر تابعی اشاره کنند.

چندگانه‌سازی (Multicasting) نماینده چیست؟

چندگانه‌سازی واسطه به این معناست که می‌توان چندین متد را به یک واسطه متصل کرد و در یک فراخوانی، تمام آن متدها اجرا می‌شوند. از عملگر += برای افزودن متدها و -= برای حذف آن‌ها استفاده می‌شود.

آیا نماینده‌ها فقط برای متدهای نمونه (Instance Methods) استفاده می‌شوند؟

خیر، واسطه‌ها می‌توانند هم برای متدهای نمونه (متدهای غیر استاتیک) و هم متدهای استاتیک استفاده شوند.

تفاوت بین Delegate و رویداد (Event) چیست؟

Delegate در سی شارپ یک اشاره‌گر به متدها است و می‌تواند مستقیماً مقداردهی و اجرا شود. رویداد (Event) در واقع نوع خاصی از Delegate است که معمولاً برای مدیریت تعاملات کاربر و جلوگیری از مقداردهی مستقیم توسط کد خارجی استفاده می‌شود.

آیا چندگانه‌سازی Delegate در سی شارپ محدودیتی دارد؟

بله، متدهایی که به یک Delegate چندگانه اضافه می‌شوند باید نوع بازگشتی void داشته باشند، در غیر این صورت، فقط مقدار بازگشتی آخرین متد ذخیره خواهد شد و سایر مقدارها از بین می‌روند.

میزان رضایتمندی
لطفاً میزان رضایت خودتان را از این مطلب با دادن امتیاز اعلام کنید.
[ امتیاز میانگین 5 از 3 نفر ]
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع و مراجع:
مجله پی استور geeksforgeeks learn

دیدگاه‌ خود را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *



برچسب‌ها:
سی شارپ


پیمایش به بالا