سه شنبه ۲۷ شهريور ۱۴۰۳
Tut24 آموزش برنامه نویسی و مجله تخصصی فناوری ورود/عضویت

آموزش سی شارپ - دلگیت‌ها

دلگیت‌های سی شارپ (C#) شبیه به اشاره‌گرها به توابع در زبان C یا C++ هستند. یک دلگیت (Delegate) یک متغیر نوع مرجع است که مرجعی به یک متد را نگه می‌دارد. این مرجع می‌تواند در زمان اجرا تغییر کند.

دلگیت‌ها به ویژه برای پیاده‌سازی رویدادها و متدهای فراخوانی باز مورد استفاده قرار می‌گیرند. همه دلگیت‌ها به طور ضمنی از کلاس System.Delegate ارث بری می‌کنند.

تعریف دلگیت‌ها

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

برای مثال، یک دلگیت را در نظر بگیرید −

public delegate int MyDelegate (string s);

دلگیت پیش‌بینی شده می‌تواند برای ارجاع به هر متدی استفاده شود که یک پارامتر رشته‌ای (string) را دریافت کند و یک متغیر نوع صحیح (int) را برگرداند.

نحو تعریف دلگیت به صورت زیر است −

delegate <return type> <delegate-name> <parameter list>

ایجاد نمونه‌های دلگیت (Instantiating Delegates)

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

public delegate void printString(string s);
...
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);

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

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

ترکیب چندین دلگیت (Multicasting of a Delegate)

شیء‌های دلگیت می‌توانند با استفاده از عملگر "+" ترکیب شوند. یک دلگیت ترکیب شده، دو دلگیتی را که از آنها تشکیل شده است، فراخوانی می‌کند. تنها دلگیت‌های هم نوع قابل ترکیب هستند. عملگر "-" می‌تواند برای حذف یک دلگیت جزئی از یک دلگیت ترکیب شده استفاده شود.

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

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 nc;
         NumberChanger nc1 = new NumberChanger(AddNum);
         NumberChanger nc2 = new NumberChanger(MultNum);
         
         nc = nc1;
         nc += nc2;
         
         //calling multicast
         nc(5);
         Console.WriteLine("Value of Num: {0}", getNum());
         Console.ReadKey();
      }
   }
}

هنگامی که کد بالا کامپایل و اجرا می شود، نتیجه زیر را ایجاد می کند -

Value of Num: 75

استفاده از دلگیت‌ها (Using Delegates)

مثال زیر استفاده از دلگیت را نشان می‌دهد. دلگیت printString می‌تواند برای ارجاع به متدی که یک رشته را به عنوان ورودی دریافت کرده و هیچ مقداری برنگرداند، استفاده شود.

ما از این دلگیت برای فراخوانی دو متد استفاده می‌کنیم، اولین متد رشته را به کنسول چاپ می‌کند و دومین متد آن را به یک فایل چاپ می‌کند −

using System;
using System.IO;

namespace DelegateAppl {

   class PrintString {
      static FileStream fs;
      static StreamWriter sw;
      
      // delegate declaration
      public delegate void printString(string s);

      // this method prints to the console
      public static void WriteToScreen(string str) {
         Console.WriteLine("The String is: {0}", str);
      }
      
      //this method prints to a file
      public static void WriteToFile(string s) {
         fs = new FileStream("c:\\message.txt",
         FileMode.Append, FileAccess.Write);
         sw = new StreamWriter(fs);
         sw.WriteLine(s);
         sw.Flush();
         sw.Close();
         fs.Close();
      }
      
      // this method takes the delegate as parameter and uses it to
      // call the methods as required
      public static void sendString(printString ps) {
         ps("Hello World");
      }
      
      static void Main(string[] args) {
         printString ps1 = new printString(WriteToScreen);
         printString ps2 = new printString(WriteToFile);
         sendString(ps1);
         sendString(ps2);
         Console.ReadKey();
      }
   }
}

هنگامی که کد بالا کامپایل و اجرا می شود، نتیجه زیر را ایجاد می کند -

The String is: Hello World