عبارات لامبدا (Lambda expressions)

عبارات لامبدا (Lambda expressions) ساده شده دستور زبان متدهای بی نام هستند. به عنوان مثال در برنامه زیر از یک متد بی نام که به یک delegate ارجاع داده شده است استفاده شده است.

using System;

public delegate void MessageDelegate(string message);

public class Program
{
    public static void Main()
    {
        MessageDelegate ShowMessage = new MessageDelegate( 
        delegate(string message)                           
        {                                                  
         Console.WriteLine(message);                       
        }                                                  
        );                                                 

        ShowMessage("Hello World!");
    }
}

به وسیله عبارات لامبدا می توان کد بالا را به صورت ساده تری نوشت :

using System;

public delegate void MessageDelegate(string message);

public class Program
{
    public static void Main()
    {
        MessageDelegate ShowMessage = (message) => Console.WriteLine(message);

        ShowMessage("Hello World!");
    }
}

مقایسه متد بی نام و عبارت لامبدا :

MyDel del = delegate(int x)    { return x + 1; } ;      // متد بی نام
MyDel le1 =         (    x) => { return x + 1; } ;     // عبارت لامبدا

در عبارت لامبدا ابتدا پارامترها را بدون ذکر نوعشان می نویسیم و بعد از عملگر => استفاده می کنیم. سپس دستوراتی را که قرار است اجرا شوند را می نویسیم. نوع پارامترها به صورت خودکار به وسیله کامپایلر تشخیص داده می شود. البته امضاء عبارات لامبدا باید شبیه به امضاء delegate باشد. عبارات لامبدا دارای اشکال زیادی هستند. به عنوان مثال در مثال بالا از یک عبارت لامبدایی استفاده کرده ایم که دارای یک دستور ساده اجرایی است. اگر delegate شما برای عبارت لامبدا هیچ پارامتری نداشته باشد، همه کاری که لازم است نجام دهید این است که هیچ پارامتری در داخل عبارت لامبدا قرار ندهید.

MessageDelegate ShowMessage = () => Console.WriteLine("Hello");

به این نکته توجه کنید که شما می توانید نوع پارامترهای عبارت لامبدا را نشان دهید.

MessageDelegate ShowMessage = (string message) => Console.WriteLine(message);

اگر نوع یک پارامتر را مشخص کنید، باید نوع سایر پارامترها را نیز مشخص کنید. به عنوان مثال نمی توانید به صورت زیر عمل کنید :

MessageDelegate ShowMessage = (string message1, message2) =>
       Console.WriteLine(message1);

اگر عبارات لامبدای شما دارای چندین دستور اجرایی باشند می توانید آنها را داخل آکولاد قرار دهید. به عبارت لامبدایی که دارای آکولاد باشد دستور لامبدا می گویند.

MessageDelegate ShowMessage = (message) =>
{
        Console.WriteLine(message);
        Console.WriteLine("Some more message");
}

در زیر مثالی از یک عبارت لامبدا که دارای مقدار برگشتی است نشان داده شده است :

SampleDelegate GetSquare = (number) => { return number * number; };

به این نکته توجه کنید که هنگام استفاده از دستور return باید همیشه از دستورات لامبدایی استفاده کنید که دارای آکولاد می باشند. اگر یک عبارت لامبدا فقط دارای یک دستور return ساده باشد می توانید به سادگی آن را به expression lambda تبدیل کنید.

SampleDelegate GetSquare = (number) => (number * number);

به این نکته توجه کنید که استفاده از پرانتز در کد بالا برای فهم بهتر آن است. اگر یک عبارت لامبدا دارای یک پارامتر ساده و یک دستور return است، می توانید برای سادگی بیشتر پرانتزها را حذف نمایید:

SampleDelegate GetSquare = number => number * number;

ولی اگر یک عبارت لامبدا دارای 2 یا تعداد بیشتری پارامتر باشد باید انها را داخل پرانتز قرار دهید.

SampleDelegate GetSum = (num1, num2) => num1 + num2;

عبارت لامبدای بالا دارای دو پارامتر است و حاصل جمع آنها را بر می گرداند.

 

یک مثال از عبارت لامبدا

با استفاده از عبارات لامبدا راحت تر می توان متدهای بی نام را به عنوان آرگومان به دیگر متد ها ارسال کرد. به مثال زیر توجه کنید :

  1: using System;                                                                       
  2:                                                                                     
  3: namespace LambdaDemo
  4: {                                                                                   
  5:     public delegate int Arithmetic(int x, int y);                                   
  6:                                                                                     
  7:     public class Program                                                            
  8:     {                                                                               
  9:         public static int GetResult(Arithmetic Operation, int num1, int num2)       
 10:         {                                                                           
 11:             return Operation(num1, num2);                                           
 12:         }                                                                           
 13:                                                                                     
 14:         public static void Main()
 15:         {                                                                           
 16:             Console.Write("Enter first number : ");                                  
 17:             int num1 = Convert.ToInt32(Console.ReadLine());                         
 18:             Console.Write("Enter second number: ");                                 
 19:             int num2 = Convert.ToInt32(Console.ReadLine());                         
 20:                                                                                     
 21:             Console.WriteLine("Sum        = " + GetResult((x, y) => x + y, num1, num2));
 22:             Console.WriteLine("Difference = " + GetResult((x, y) => x - y, num1, num2));
 23:             Console.WriteLine("Product    = " + GetResult((x, y) => x * y, num1, num2));
 24:             Console.WriteLine("Quotient   = " + GetResult((x, y) => x / y, num1, num2));
 25:         }                                                                           
 26:     }                                                                               
 27: }
Enter first number : 5
Enter second number: 2
Sum        = 7
Difference = 3
Product    = 10
Quotient   = 2

ابتدا در خط 5 یک delegate ایجاد می کنیم که دو آرگومان از نوع اعداد صحیح را قبول کرده و یک مقدار صحیح را بر می گرداند. سپس از این delegate به عنوان یکی از پارامترهای متد GetResult() استفاده می کنیم(خطوط 12-9). دو پارامتر دیگر، دو عدد هستند که همانطور که خواهیم دید در عملیاتهای مختلف نقش دارند. از آنجاییکه اولین پارامتر یک delegate است، آرگومانی که به آن ارسال می شود باید مرجع یک متد ، یا یک متد بی نام  و یا یک عبارت لامبدا باشد. با استفاده از عبارت لامبدا می توان کدهای خواناتری نوشت و همچنین کدنویسی را کاهش داد. در خطوط 24-21 متد GetResult را فراخوانی می کنیم. توجه کنید که متد در هر فراخوانی یک عبارت لامبدا را به عنوان اولین آرگومان قبول می کند. اگر از متدهای بی نام استفاده می کردیم، نیاز به کدنویسی بیشتری داشتیم و خوانایی آن نیز کمتر می شد.

لطفا اگر نظر، پیشنهاد و یا انتقادی در باره مطلب بالا دارید در قسمت زیر و اگر سوالی دارید در بخش پرسش و پاسخ مطرح بفرمایید.

  1. مسعود پاسخ دادن

    با سلام
    تشکر از همه مطالبی به جا و جالب تون….
    درس های بعدی رو کی برای استفاده خواهید گذاشت…

  2. ahmad پاسخ دادن

    از مطالب عالی و کاربری سایت شما متشکرم

  3. شریف پاسخ دادن

    واقعن ممنون ..فوق العادست مطالبتون