🎯 متدهای هدف (Target Methods): Static یا Instance؟
متد هدف یک دلیگیت (Delegate) میتواند یک متد محلی (local)، Static یا Instance باشد. 💡
🔹 متد هدف Static
مثال زیر یک متد هدف Static را نشان میدهد:
Transformer t = Test.Square;
Console.WriteLine (t(10)); // خروجی: 100
class Test { public static int Square (int x) => x * x; }
delegate int Transformer (int x);
🔸 متد هدف Instance
مثال زیر یک متد هدف Instance را نشان میدهد:
Test test = new Test();
Transformer t = test.Square;
Console.WriteLine (t(10)); // خروجی: 100
class Test { public int Square (int x) => x * x; }
delegate int Transformer (int x);
🧠 نحوه عملکرد با Instance Methodها
هنگامی که یک متد Instance به یک شیء دلیگیت اختصاص داده میشود، آن شیء نه تنها یک رفرنس به خود متد، بلکه یک رفرنس به نمونه (Instance) که متد به آن تعلق دارد، را نیز حفظ میکند. 🤝
خاصیت Target از کلاس System.Delegate نشاندهنده همین نمونه است (و برای دلیگیتی که به یک متد Static اشاره میکند، null خواهد بود).
مثالی از حفظ Instance:
MyReporter r = new MyReporter();
r.Prefix = "%Complete: ";
ProgressReporter p = r.ReportProgress;
p(99); // خروجی: %Complete: 99
Console.WriteLine (p.Target == r); // خروجی: True
Console.WriteLine (p.Method); // خروجی: Void ReportProgress(Int32)
r.Prefix = "";
p(99); // خروجی: 99
public delegate void ProgressReporter (int percentComplete);
class MyReporter
{
public string Prefix = "";
public void ReportProgress (int percentComplete)
=> Console.WriteLine (Prefix + percentComplete);
}
از آنجایی که نمونه در خاصیت Target دلیگیت ذخیره میشود، طول عمر آن حداقل تا زمانی که طول عمر دلیگیت است، تمدید میشود. 🕰
⛓️ دلیگیتهای چندپخشی (Multicast Delegates)
تمامی نمونههای دلیگیت قابلیت چندپخشی (Multicast) دارند. این بدان معناست که یک نمونه دلیگیت میتواند نه تنها به یک متد هدف، بلکه به لیستی از متدهای هدف اشاره کند.
➕ ترکیب (Combine) دلیگیتها
اپراتورهای + و += نمونههای دلیگیت را ترکیب میکنند:
SomeDelegate d = SomeMethod1;
d += SomeMethod2;
فراخوانی d اکنون هر دو متد SomeMethod1 و SomeMethod2 را صدا میزند. دلیگیتها به همان ترتیبی که اضافه شدهاند، فراخوانی میشوند. ➡️
➖ حذف (Remove) دلیگیتها
اپراتورهای - و -= عملوند دلیگیت سمت راست را از عملوند دلیگیت سمت چپ حذف میکنند:
d -= SomeMethod1;
فراخوانی d اکنون تنها باعث فراخوانی SomeMethod2 میشود.
💡 نکات تکمیلی
فراخوانی + یا += روی یک متغیر دلیگیت با مقدار null کار میکند و معادل تخصیص یک مقدار جدید به متغیر است.
دلیگیتها تغییرناپذیر (Immutable) هستند، بنابراین وقتی شما += یا -= را فراخوانی میکنید، در واقع یک نمونه دلیگیت جدید ایجاد کرده و آن را به متغیر موجود اختصاص میدهید. 🔄
⚠️ مقادیر بازگشتی در Multicast
اگر یک دلیگیت چندپخشی نوع بازگشتی غیر void داشته باشد، فراخواننده مقدار بازگشتی را از آخرین متدی که فراخوانی شده است، دریافت میکند. متدهای قبلی همچنان فراخوانی میشوند، اما مقادیر بازگشتی آنها نادیده گرفته میشوند.
🖥 مثال عملی از Multicast Delegate
متد HardWork یک پارامتر دلیگیت ProgressReporter دارد که برای گزارش پیشرفت کار از آن استفاده میشود:
public delegate void ProgressReporter (int percentComplete);
public class Util
{
public static void HardWork (ProgressReporter p)
{
for (int i = 0; i < 10; i++)
{
p (i * 10); // Invoke delegate
System.Threading.Thread.Sleep (100); // Simulate hard work
}
}
}
برای نظارت بر پیشرفت، میتوانیم دو متد مستقل را ترکیب کنیم:
ProgressReporter p = WriteProgressToConsole;
p += WriteProgressToFile; // ترکیب دو متد
Util.HardWork (p);
void WriteProgressToConsole (int percentComplete)
=> Console.WriteLine (percentComplete);
void WriteProgressToFile (int percentComplete)
=> System.IO.File.WriteAllText ("progress.txt",
percentComplete.ToString());
🔖 هشتگها:
#CSharp #Delegates #Multicast #OOP #AdvancedCSharp