ویرگول
ورودثبت نام
سمانه شریفی
سمانه شریفی
سمانه شریفی
سمانه شریفی
خواندن ۳ دقیقه·۱ ماه پیش

درک کامل Delegate و Func در C#

در زبان C#، توابع هم داده هستند.
یعنی می‌توانیم آن‌ها را به متغیرها نسبت دهیم، به عنوان پارامتر به متدها ارسال کنیم، یا حتی در لیست‌ها ذخیره کنیم.
پایه‌ی این قابلیت در C#، مفهومی است به نام Delegate.

Delegateها به همراه Func<> و Action<> یکی از مهم‌ترین ابزارهای برنامه‌نویسی مدرن در دات‌نت محسوب می‌شوند.
در این مقاله به‌صورت مفهومی و کاربردی یاد می‌گیریم Delegate چیست، Func چه تفاوتی دارد، و در چه موقعیت‌هایی استفاده می‌شوند.


🔹 Delegate چیست؟

به زبان ساده، Delegate نوعی متغیر است که می‌تواند به یک تابع اشاره کند.
در واقع اشاره‌گر به تابع (Function Pointer) در دات‌نت است.

با استفاده از Delegate می‌توانیم تابعی را:

  • در یک متغیر نگه داریم

  • به متد دیگر ارسال کنیم

  • یا در زمان اجرا تصمیم بگیریم کدام تابع اجرا شود


✳️ مثال ساده از تعریف و استفاده از Delegate

// تعریف delegate delegate void MyDelegate(); // تابعی که با آن سازگار است void SayHello() { Console.WriteLine("Hello!"); } // استفاده از delegate MyDelegate d = SayHello; d(); // خروجی: Hello!

در این مثال:

  • MyDelegate نوعی delegate است که به هر تابعی با امضای void() اشاره می‌کند.

  • متغیر d اکنون تابع SayHello را در خود نگه می‌دارد.

  • با اجرای d() در واقع همان تابع SayHello فراخوانی می‌شود.


🔸 Delegate با پارامتر و خروجی

Delegateها می‌توانند پارامتر ورودی و مقدار خروجی هم داشته باشند:

delegate int MathOperation(int a, int b); int Add(int x, int y) => x + y; int Multiply(int x, int y) => x * y; void RunOperation(MathOperation op) { Console.WriteLine(op(3, 4)); } RunOperation(Add); // 7 RunOperation(Multiply); // 12

در این مثال، تابع RunOperation خودش تابعی از نوع MathOperation را به عنوان پارامتر دریافت می‌کند.
این دقیقاً همان مفهوم ارسال تابع به تابع دیگر (Higher-Order Function) است.


🔸 Lambda و Delegate

در C# برای راحت‌تر نوشتن delegateها، از Lambda Expression استفاده می‌شود.
Lambda یعنی تابع بی‌نام:

MathOperation subtract = (a, b) => a - b; Console.WriteLine(subtract(10, 3)); // خروجی: 7

🔹 Func<> چیست؟

Func<> در واقع یک نوع Delegate آماده است که در خود دات‌نت تعریف شده.
نیازی نیست هر بار delegate جدید بنویسی.

قانون کلی:

Func همیشه خروجی دارد (Return Value).


✳️ ساختار Func

Func<T1, T2, ..., TResult>
  • تمام پارامترهای اولی (T1, T2, ...) ورودی تابع هستند

  • آخرین پارامتر (TResult) خروجی تابع است


📘 مثال‌های ساده از Func

Func<int> getNumber = () => 5; Console.WriteLine(getNumber()); // 5 Func<int, int> square = x => x * x; Console.WriteLine(square(4)); // 16 Func<int, int, int> add = (a, b) => a + b; Console.WriteLine(add(3, 7)); // 10

در همهٔ این مثال‌ها، ما تابع را در قالب یک متغیر از نوع Func ذخیره کرده‌ایم.


🔸 Action در مقابل Func

اگر تابع خروجی ندارد، از Action استفاده می‌کنیم:

نوعخروجی دارد؟مثالFunc<int, int>✅ دارد (int برمی‌گرداند)x => x * 2Action<string>❌ ندارد (void است)x => Console.WriteLine(x)


🧩 ترکیب Delegate و Func در دنیای واقعی

در سیستم‌های مدرن (مثلاً ASP.NET Core)، از Func و delegate برای طراحی صف کار (Background Queue) استفاده می‌شود.
مثلاً متد زیر در یک صف کاری وجود دارد:

void Enqueue(Func<CancellationToken, Task> workItem);

یعنی:

تابعی را بفرست که یک CancellationToken می‌گیرد و یک Task برمی‌گرداند (یعنی کاری async انجام می‌دهد).

کاربردش چیست؟
ارسال کارهایی مثل ارسال ایمیل، ثبت گزارش، یا Sync با APIها به صفی که در پس‌زمینه اجرا می‌شود.

مثال:

queue.Enqueue(async token => { await Task.Delay(2000, token); Console.WriteLine("Job done!"); });

🔍 مزیت‌های استفاده از Delegate و Func

✅ جدا کردن منطق از ساختار
✅ افزایش انعطاف در طراحی (قابلیت پاس دادن رفتار به متدها)
✅ کاهش تکرار کد
✅ پشتیبانی از الگوهای تابعی (Functional Patterns)
✅ کاربرد گسترده در LINQ، async/await، و eventها


🧠 جمع‌بندی

مفهومتعریفمثالDelegateنوع داده‌ای که به یک تابع اشاره می‌کندdelegate void MyDelegate();FuncDelegate آماده برای توابع دارای خروجیFunc<int, int, int> add = (a,b)=>a+b;ActionDelegate آماده برای توابع بدون خروجیAction<string> show = s => Console.WriteLine(s);


🔹 جمله طلایی

Delegate پایه‌ی همه‌ی الگوهای callback، event، async task، LINQ و middleware در دات‌نت است.
Func<> و Action<> فقط نسخه‌های راحت‌تر و از پیش‌تعریف‌شدهٔ آن هستند.

delegatequeue
۰
۰
سمانه شریفی
سمانه شریفی
شاید از این پست‌ها خوشتان بیاید