• مفهوم واژه Delegate در سی شارپ

    نماینده ساز یا Delegate در سی شارپ چیست و چه کاری انجام می دهد، نحوه کار با نماینده ساز ها چطوریست

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

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

     
    public delegate int PerformCalculation(int x, int y);

    هر متدی از هر کلاس یا ساختار قابل دسترسی که با نوع نماینده مطابقت داشته باشد را می توان به نماینده اختصاص داد. روش می تواند استاتیک یا روش نمونه باشد. این انعطاف‌پذیری به این معنی است که می‌توانید به‌طور برنامه‌نویسی فراخوانی‌های متد را تغییر دهید یا کدهای جدید را به کلاس‌های موجود اضافه کنید.

    توجه داشته باشید

    در زمینه بارگذاری بیش از حد متد، امضای یک روش شامل مقدار بازگشتی نمی شود. اما در زمینه نمایندگان، امضا شامل مقدار بازگشتی است. به عبارت دیگر، یک متد باید دارای همان نوع بازگشتی با نماینده باشد.

     

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

    نشانگرهای تابع برای سناریوهای مشابه به C# 9 اضافه شدند، جایی که شما نیاز به کنترل بیشتری بر روی کنوانسیون تماس دارید. کد مرتبط با یک نماینده با استفاده از یک روش مجازی که به یک نوع نماینده اضافه شده است فراخوانی می شود. با استفاده از نشانگرهای تابع، می توانید قراردادهای مختلفی را مشخص کنید.

    بررسی اجمالی نمایندگان

    • Delegates شبیه به نشانگرهای تابع C++ هستند، اما نماینده ها کاملاً شی گرا هستند و برخلاف اشاره گرهای C++ به توابع عضو، نماینده ها هم یک نمونه شی و هم یک متد را کپسوله می کنند.
    • نمایندگان اجازه می دهند تا متدها به عنوان پارامتر ارسال شوند.
    • از نمایندگان می توان برای تعریف روش های برگشت به تماس استفاده کرد.
    • نمایندگان را می توان به زنجیر کرد. برای مثال، چندین متد را می توان در یک رویداد فراخوانی کرد.
    • لازم نیست روش ها دقیقاً با نوع نماینده مطابقت داشته باشند. برای اطلاعات بیشتر، استفاده از Variance در Delegates را ببینید .
    • عبارات لامبدا روشی مختصرتر برای نوشتن بلوک های کد درون خطی هستند. عبارات لامبدا (در زمینه های خاص) برای تفویض انواع کامپایل می شوند. برای اطلاعات بیشتر در مورد عبارات لامبدا، عبارات لامبدا را ببینید .

    استفاده از Delegate

    Delegate نوعی است که به طور ایمن یک متد را شبیه به یک اشاره گر تابع در C و C++ می کند . برخلاف نشانگرهای تابع C، نمایندگان شی گرا هستند، تایپ می کنند ایمن و ایمن هستند. نوع نماینده با نام نماینده مشخص می شود. مثال زیر نماینده ای را با نام اعلام می کند Callbackکه می تواند متدی را کپسوله کند که یک رشته را به عنوان آرگومان می گیرد و void برمی گرداند :

     
    public delegate void Callback(string message);
    

    یک شیء نماینده معمولاً با ارائه نام روشی که نماینده می‌پیچد، یا با عبارت لامبدا ساخته می‌شود . هنگامی که یک نماینده نمونه سازی شد، یک فراخوانی متدی که به نماینده داده شده است توسط نماینده به آن متد ارسال می شود. پارامترهایی که توسط فراخوان به نماینده ارسال می شود به متد ارسال می شود و مقدار برگشتی، در صورت وجود، از متد توسط نماینده به فراخوان دهنده بازگردانده می شود. این به استناد نماینده معروف است. یک نماینده نمونه را می توان به گونه ای فراخوانی کرد که گویی خود روش پیچیده شده است. مثلا:

     
    // Create a method for a delegate.
    public static void DelegateMethod(string message)
    {
        Console.WriteLine(message);
    }
    
    // Instantiate the delegate.
    Callback handler = DelegateMethod;
    
    // Call the delegate.
    handler("Hello World");

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

    یکی دیگر از کاربردهای متداول callback ها، تعریف یک روش مقایسه سفارشی و انتقال آن به یک روش مرتب سازی است. این اجازه می دهد تا کد تماس گیرنده به بخشی از الگوریتم مرتب سازی تبدیل شود. روش مثال زیر از Delنوع به عنوان پارامتر استفاده می کند:

    public static void MethodWithCallback(int param1, int param2, Callback callback)
    {
        callback("The number is: " + (param1 + param2).ToString());
    }
    MethodWithCallback(1, 2, handler);
    
    //Console 
    The number is: 3
    

    استفاده از نماینده به عنوان یک انتزاع، MethodWithCallbackنیازی به فراخوانی مستقیم کنسول ندارد - لازم نیست که با یک کنسول طراحی شود. کاری MethodWithCallbackکه انجام می دهد این است که به سادگی یک رشته آماده کرده و رشته را به روش دیگری منتقل می کند. این به ویژه قدرتمند است زیرا یک روش واگذار شده می تواند از هر تعداد پارامتر استفاده کند.

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

    public class MethodClass
    {
        public void Method1(string message) { }
        public void Method2(string message) { }
    }

    همراه با استاتیکی DelegateMethodکه قبلا نشان داده شد، اکنون سه روش داریم که می‌توان آنها را با یک Delنمونه پیچیده کرد.

    یک نماینده می تواند بیش از یک متد را هنگام فراخوانی فراخوانی کند. این به عنوان پخش چندگانه نامیده می شود. برای افزودن یک روش اضافی به لیست متدهای نماینده - لیست فراخوانی - به سادگی نیاز است که دو نماینده با استفاده از عملگرهای تخصیص جمع یا جمع اضافه کنید ('+' یا '+='). مثلا:

     
    var obj = new MethodClass();
    Callback d1 = obj.Method1;
    Callback d2 = obj.Method2;
    Callback d3 = DelegateMethod;
    
    //Both types of assignment are valid.
    Callback allMethodsDelegate = d1 + d2;
    allMethodsDelegate += d3;

    در این مرحله allMethodsDelegateشامل سه روش در لیست فراخوانی خود می باشد— Method1، Method2و DelegateMethod. سه نماینده اصلی، d1, d2و d3, بدون تغییر باقی می مانند. چه زمانیallMethodsDelegateفراخوانی می شود، هر سه روش به ترتیب فراخوانی می شوند. اگر نماینده از پارامترهای مرجع استفاده کند، ارجاع به ترتیب به هر یک از سه روش به نوبه خود ارسال می شود و هرگونه تغییر در یک متد برای متد بعدی قابل مشاهده است. هنگامی که هر یک از متدها استثنایی را ایجاد می کند که در متد قرار نمی گیرد، آن استثنا به فراخوان دهنده نماینده ارسال می شود و هیچ متد بعدی در لیست فراخوانی فراخوانی نمی شود. اگر نماینده یک مقدار بازگشتی و/یا پارامترهای خروجی داشته باشد، مقدار بازگشتی و پارامترهای آخرین متد فراخوانی شده را برمی‌گرداند. برای حذف یک روش از فهرست فراخوانی، از عملگرهای تخصیص تفریق یا تفریق ( -یا -=) استفاده کنید. مثلا:

     
    //remove Method1
    allMethodsDelegate -= d1;
    
    // copy AllMethodsDelegate while removing d2
    Callback oneMethodDelegate = allMethodsDelegate - d2;
    

    از آنجایی که انواع delegate از نشأت می گیرند System.Delegate، متدها و ویژگی های تعریف شده توسط آن کلاس را می توان در delegate فراخوانی کرد. برای مثال، برای یافتن تعداد روش‌ها در فهرست فراخوانی یک نماینده، می‌توانید بنویسید:

     
    int invocationCount = d1.GetInvocationList().GetLength(0);

    نمایندگان با بیش از یک روش در فهرست فراخوانی خود از MulticastDelegate که زیر کلاسی از System.Delegate. کد بالا در هر صورت کار می کند زیرا هر دو کلاس پشتیبانی می کنند GetInvocationList.

    نمایندگان Multicast به طور گسترده در مدیریت رویداد استفاده می شوند. اشیاء منبع رویداد اعلان رویداد را به اشیاء گیرنده ای که برای دریافت آن رویداد ثبت نام کرده اند ارسال می کنند. برای ثبت نام برای یک رویداد، گیرنده متدی را ایجاد می کند که برای مدیریت رویداد طراحی شده است، سپس یک نماینده برای آن متد ایجاد می کند و نماینده را به منبع رویداد ارسال می کند. منبع هنگام وقوع رویداد، نماینده را فرا می خواند. سپس نماینده، روش مدیریت رویداد را بر روی گیرنده فراخوانی می‌کند و داده‌های رویداد را تحویل می‌دهد. نوع نماینده برای یک رویداد معین توسط منبع رویداد تعریف می شود. برای اطلاعات بیشتر، رویدادها را ببینید .

    مقایسه نمایندگان دو نوع مختلف اختصاص داده شده در زمان کامپایل منجر به خطای کامپایل می شود. اگر نمونه های نمایندگی به طور ایستا از نوع باشند System.Delegate، مقایسه مجاز است، اما در زمان اجرا false برمی گردد. مثلا:

     
    delegate void Callback1();
    delegate void Callback2();
    
    static void method(Callback1 d, Callback2 e, System.Delegate f)
    {
        // Compile-time error.
        //Console.WriteLine(d == e);
    
        // OK at compile-time. False if the run-time type of f
        // is not the same as that of d.
        Console.WriteLine(d == f);
    }
    نظرات ارسال شده ارسال نظر جدید
    برای تبادل نظر، می بایست در سایت وارد شوید

    ورود به سایت
تماس سبد خرید بالا