حسین احمدی
بنیانگذار توسینسو و برنامه نویس و توسعه دهنده ارشد وب

آموزش استفاده از Lambda Expression و Anonymous Method در سی شارپ

در آموزشی که راجع به Delegate ها صحبت کردیم، گفتیم Delegate ها به ما این قابلیت را می دهند تا بتوانیم در یک متغیر، یک متد را قرار دهیم. اما اینکار نیاز به این داشت که ابتدا یک متد تعریف کرده و سپس نام آن متد را داخل متغیر بریزیم. برای اینکار، راه حل دیگری نیز وجود دارد، می توانیم بدون نیاز به تعریف یک متد، مستقیماً متد مورد نظر را زمان انتساب تعریف کنیم. به نظرم بررسی یک مثال موضوع رو بیشتر روشن می کنه. فرض کنید Delegate ای را به صورت زیر تعریف کردیم:

دوره های شبکه، برنامه نویسی، مجازی سازی، امنیت، نفوذ و ... با برترین های ایران

برای یادگیری و آموزش سی شارپ ( آموزش زبان برنامه نویسی سی شارپ ) رایگان به این لینک بروید

public delegate int MathAction(int number1, int number2);


برای استفاده از Delegate بالا، باید ابتدا متدی را تعریف کرده و سپس داخل متغیری از نوع این delegate قرار دهیم:

class Program
{
    static void Main(string[] args)
    {
        MathAction sum = Sum;
    }

    public static int Sum(int n1, int n2)
    {
        return n1 + n2;
    }
}


با استفاده از Anonymous Method یا متدهای بی نام دیگر نیازی به تعریف متد نخواهد بود، کافیست به صورت زیر عمل کنیم:

MathAction sum = delegate(int n1, int n2)
{
    return n1 + n2;
};

Console.WriteLine(sum(2 , 4));

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

public static void DisplayResult(int n1, int n2, MathAction mathAction)
{
    Console.WriteLine(mathAction(n1, n2));
}

دو پارامتر از نوع int و یک پارامتر از نوع MathAction دریافت کرده و داخل متد، نتیجه خروجی mathAction را چاپ می کند، استفاده از متد بالا با استفاده از Anonymous Method به صورت زیر است:

DisplayResult(2, 6, delegate(int n1, int n2) { return n1 + n2; });
DisplayResult(2, 6, delegate (int n1, int n2) { return n1 * n2; });

متد اول حاصل جمع و متد دوم حاصل ضرب دو عدد 2 و 6 را در خروجی چاپ می کند.

Lambda Expression ها در سی شارپ

با کمک Lambda Expression ها، می توان متدهای بدون نام را به شکل ساده تری نوشت، قطعه کدی که در بالا نوشتیم را در زیر تکرار می کنیم:

MathAction sum = delegate(int n1, int n2)
{
    return n1 + n2;
};

اگر بخواهیم کد بالا را بر اساس Lambda Expression ها بنویسیم، به صورت زیر کد تغییر می کند:

MathAction sum = (n1, n2) =>
{
    return n1 + n2;
};

تغییری که داده شده، ابتدا کلمه کلیدی delegate را حذف کردیم، بعد پارامترهای ورودی دیگر نیازی به نوشتن نوع داده (Data Type) ندارند، کامپایلر به صورت خودکار و بر اساس Delegate مورد استفاده، نوع پارمتر ها را تشخیص می دهد، بعد از مشخص کردن پارامتر ها، علامت <= نوشته می شود، این علامت به کامپایلر می گوید عبارت نوشته شده، یک Lambda Expression است. در مورد Lambda Expression ها، یکسری نکات وجود دارد که آن ها را بررسی می کنیم:

1. در صورتی که delegate تعریف شده، تنها یک پارامتر داشته باشد، نیازی به نوشتن پرانتز برای پارامتر ها نیست:

public delegate int MyDelegate(int param);

// Usage
MyDelegate action = p => { return p*2; };


2. در صورتی که بدنه متد تنها شامل یک دستور باشد، می توان از نوشتن {} و کلمه کلیدی return چشم پوشی کرد:

public delegate int MyDelegate(int param);

// Usage
MyDelegate action = p => p*2;


در کد بالا، حاصل p*2 به عنوان خروجی بازگردانده می شود. در حقیقت، Lambda Expression ها، یک حالت خلاصه نویسی برای متدهای بدون نام هستند که کار ما را خیلی راحت تر می کنند و همینطور کاربرد زیادی در LINQ دارند.


Delegate های Generic در سی شارپ

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

public delegate TOut DoTask<tout, tparameter1,="" tparameter2="">(TParameter1 p1, TParameter2 p2);
</tout,>


همانطور که مشاهده می کنید، در کد بالا، DoTask شامل سه پارامتر generic است که یکی از آن ها برای خروجی و دو تای دیگر برای ورودی استفاده شدند. حال می توان از delegate بالا به صورت زیر استفاده کرد:

DoTask<string, int,="" int=""> action = (p1, p2) =>
{
    return (p1*p2).ToString();
};
</string,>

همانطور که مشاهده می کنید، نوع بازگشتی از نوع string و پارامترهای ورودی از نوع int در نظر گرفته شده اند و داخل بدنه متدی که تعریف کردیم، حاصل ضرب دو پارامتر p1 و p2 تبدیل به نوع رشته شده و به عنوان خروجی بازگردانده می شوند. تمام قابلیت هایی که برای generic ها توضیح دادیم، مانند Constraint ها، برای delegate ها هم قابل اعمال هستند. در این مبحث، با متدهای بدون نام، Lambda Expression ها و همینطور delegate های generic آشنا شدیم. امیدوارم مورد توجه شما دوستان قرار گرفته باشد.


حسین احمدی
حسین احمدی

بنیانگذار توسینسو و برنامه نویس و توسعه دهنده ارشد وب

حسین احمدی ، بنیانگذار TOSINSO ، توسعه دهنده وب و برنامه نویس ، بیش از 12 سال سابقه فعالیت حرفه ای در سطح کلان ، مشاور ، مدیر پروژه و مدرس نهادهای مالی و اعتباری ، تخصص در پلتفرم دات نت و زبان سی شارپ ، طراحی و توسعه وب ، امنیت نرم افزار ، تحلیل سیستم های اطلاعاتی و داده کاوی ...

نظرات