نماینده ها(Delegates)

delegate ها انواعی هستند که مرجع یک متد را در خود ذخیره می‌کنند. همچنین می‌توانند رفتار هر متدی را کپی برداری کنند. برای تعریف یک delegateاز کلمه کلیدی delegate استفاده می‌شود. تعریف یک delegate بسیار شبیه به تعریف یک متد است با این تفاوت که متد بدنه دارد ولی delegate ندارد. delegate دقیقاً مانند متدها دارای نوع برگشتی و مجموعه‌ای از پارامترها هستند. delegate ها می گویند که چه نوع متدی را می‌توانند در خود ذخیره کنند. به زبان ساده delegate ها را می‌توان به عنوان یک ظرف در نظر گرفت که می‌توانید هر تعداد متد را که دوست دارید را در داخل آن قرار دهید. زمانی که شما delegate را فراخوانی می‌کنید تک به تک متدهای داخل آن اجرا می‌شوند. در زیر نحوه تعریف delegate نشان داده شده است :

delegate returnType DelegateName(dt param1, dt param2, ... dt paramN);

در زیر نحوه استفاده از یک delegate و فواید آن نشان داده شده است :

  1: using System;                                            
  2:                                                          
  3: public class Program                                     
  4: {                                                        
  5:     delegate void ArithmeticDelegate(int num1, int num2);
  6:                                                          
  7:     static void Add(int x, int y)                        
  8:     {                                                    
  9:         Console.WriteLine("Sum is {0}.", x + y);         
 10:     }                                                    
 11:                                                          
 12:     static void Subtract(int x, int y)                   
 13:     {                                                    
 14:         Console.WriteLine("Difference is {0}.", x - y);  
 15:     }                                                    
 16:                                                          
 17:     static void Main()                                   
 18:     {                                                    
 19:         ArithmeticDelegate Operation;                  
 20:                                                          
 21:         int num1, num2;                                  
 22:                                                          
 23:         Console.Write("Enter first number: ");           
 24:         num1 = Convert.ToInt32(Console.ReadLine());      
 25:                                                          
 26:         Console.Write("Enter second number: ");          
 27:         num2 = Convert.ToInt32(Console.ReadLine());      
 28:                                                          
 29:         if (num1 < num2)                              
 30:         {                                                
 31:             Operation = new ArithmeticDelegate(Add);     
 32:         }                                                
 33:         else                                             
 34:         {                                                
 35:             Operation = new ArithmeticDelegate(Subtract);
 36:         }                                                
 37:                                                          
 38:         Operation(num1, num2);                           
 39:     }                                                    
 40: }
Enter first number: 3
Enter second number: 5
Sum is 8
Enter first number: 5
Enter second number: 3
Difference is 2

در خط 5 یک نماینده تعریف شده است. از کلمه کلیدی delegate برای نشان داده آن استفاده شده است. به دنبال آن نوع برگشتی متدی که قبول می‌کند هم آمده است. برای نامگذاری delegate مانند متدها از روش Pascal استفاده می‌کنیم. همچنین برای تشخیص بهتر آنها بهتر است از کلمه delegate در نامگذاری آن‌ها استفاده شود.

پارامترهایی که برای delegate تعریف می‌کنیم باید از نظر نوع و تعداد با پارامترهای متدها برابر باشد. delegate ی که در خط 5 تعریف شده است فقط مرجع متدهایی را قبول می‌کند دارای مقدار برگشتی نیستند و دو پارامتر از نوع int دارند. بعد از تعریف delegate دو متد با امضای دقیقاً مشابه با امضای delegate تعریف می‌کنیم .

هر دو متد هیچ مقداربرگشتی ندارند و هر دو، 2 آرگومان از نوع int قبول می‌کنند. در داخل متد Main یک متغیر از نوع delegate ی که قبلاً تعریف کرده‌ایم، تعریف می‌کنیم (خط 1۹). این متغیر اشاره به متدی دارد که امضای آن با امضای delegate مطابقت دارد. برنامه از کاربر می‌خواهد دو مقدار از نوع int را وارد کند.

بعد از وارد کردن مقادیر وارد اولین دستور if می‌شویم، چنانچه مقدار اولین عددی که کاربر وارد کرده از دومین عدد وارد شده کمتر باشد، دو عدد با هم جمع می‌شوند. در غیر اینصورت اگر مقدار اولین عدد بزرگتر یا مساوی دومین عدد باشد از هم کم می‌شوند. برای ارجاع یک متد به یک delegate به صورت زیر عمل می‌کنیم :

variable = new DelegateName(MethodName);

وقتی یک delegate را با یک مرجع متد برابر قرار می‌دهیم باید قبل از نام delegate از کلمه کلیدی new استفاده کنیم (مثال بالا). در داخل پرانتز نام متدی که delegate به آن مراجعه می‌کند نشان داده شده است. یک راه بسیار ساده‌تر برابر قرار دادن نام متد با متغیر delegate است :

Operation = Add;
Operation = Subtract;

به دستور if بر می‌گردیم وقتی شرط درست باشد، delegate را به متد add() و هنگامی که شرط نادرست باشد آن را به متد Subtract() ارجاع می‌دهیم. اجرای delegate باعث اجرای متدی می‌شود که delegate به آن مراجعه می‌کند. اگر قصد داشته باشید که بیش از یک متد را به delegate اضافه کنید باید از عملگر =+ استفاده نمایید :

MyDelegate del = Method1;
del += Method2;
del += Method3;   
...