تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
[مقال] Lambda expressions تعابير لمدا من وجهة نظر عملية
#1
Lightbulb 
بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله وبركاته
أردت ان اشرح تعابير لمدا في C# من وجهة نظر التطبيق، وقد يكون الشرح مخل بعض الشيء ولكن الاهم هو ان تصل المعلومة باذن الله سنبدأ بالتعريف ثم نتجه الى التطبيق ان شاء الله .

التعريف :

تعابير Lambda هي عبارة عن اجراء او دالة ليس لها اسم وتعود بقيمة واحدة إذا كانت تمثل دالة او لاتعود باي قيمة اذا كانت تمثل اجراء
يأخذ تعبير لمبدا الشكل العام التالي :

كود :
(المدخلات) => {جسم التعبير او العمليات على المدخلات}



يعني ببساطة كأننا نقول للمترجم للمدخلات التالية كذا وكذا افعل كذا وكذا .



بالنسبة للمدخلات فانها من الممكن ان تكون :

مدخل واحد : التعبير التالي يرجع  ضعف الرقم المدخل ، لا حاجة لاستخدام الاقواس () هنا بما انه مدخل واحد :


كود :
x => x*2


اكثر من مدخل : التعبير التالي يحسب مجموع ثلاث ارقام مدخلة :


كود :
(a, b, c) => a + b + c

بدون مدخلات :
يمكن استخدام تعبير لمدا بدون مدخلات ، ويستخدم الاقواس الفارغة () للتعبير على انه بدون مدخلات ، التعبير التالي يعيد قيمة ثابتة 2 بدون اي مدخل :

كود :
() => 2


بالنسبة لجسم تعبير لمدا فانه من الممكن ان يتكون من :

سطر واحد : عند صياغة تعبير لمدا في سطر واحد فانه يمكنك كتابة السطر بعد العلامة => مباشرة دول الحاجة للاقواس {}مثل المثال السابق الذي يرجع ضعف الرقم المدخل:


كود :
x => x*2
 
اكثر من سطر : اذا اردت استخدام اكثر من سطر في جسم تعبير لمدا يجب ان تحيطهم باقواس {} ، وكذلك يجب ان تحدد المخرجات يدويا باستخدام Return في حالة ما كان التعبير يمثل دالة طبعا .
التعبير التالي يضيف نقطة في نهاية الكلمة ثم يعرضها في رسالة :


كود :
            Action<string> AddToString =
                s =>
                {
                    s += ".";
                    MessageBox.Show(s);
                };


التعبير التالي يقوم بتربيع رقم واعادة النتيجة :


كود :
            Func<int, int> SquareThis =
                x =>
                {
                    x *= x;
                    return x;
                };



 صحيح ان تعبير لمدا لايأخد اسم ولكن يمكنك ان تسنده لكائن من نوع Func<> اذا كان يمثل دالة او Action<> اذا كان يمثل اجراء
ويعامل معاملة الدوال او الاجراءات المعرفة مسبقا ، فعند استدعاء الكائن يقوم باستدعاء تعبير لمدا الذي يشير اليه :


كود :
            Func<int, int> DoubleThis = x => x * 2;
            label1.Text =DoubleThis(3).ToString(); //6

نلاحظ انه يجب عليك تحديد نوع المدخلات والناتج عند استخدام Func<> بين الاقواس <> حيث تعرف نوع المدخلات اولا ثم نوع النتيجة ، والفصل بينهم بالفاصلة العادية , كالمثال الذي في موقع ميكروسوفت ، تعبير لمدا هنا يعيد قيمة bool تمثل اذا كان النص المدخل string اكبر من طول محدد int :


كود :
Func<int, string, bool> isTooLong = ( x,  s) => s.Length > x;


وكذلك الامر بالنسبة ل Action التي تشير الى تعبير لمدا يمثل اجراء لايعود بقيمة :

كود :
Action<string> ShowMsgBox = m => MessageBox.Show(m); //تعريف الاجراء
            ShowMsgBox("action !"); //استدعاء الاجراء


نلاحظ انه يجب عليك ايضا تحديد نوع المدخلات عند استخدام Action<> بين الاقواس <> والفصل بينهم بالفاصلة العادية ,
وفي حالة ما كان الاجراء لا يأخذ اي مدخلات ، لايتم استخدام اقواس <> وتكتب Action فقط هكذا :


كود :
           Action ShowNewForm1 = () => new Form1().Show();

الاجراء السابق يستخدم تعبير لمدا بدون مدخلات يقوم بعرض نسخة جديدة من form1 .

وبما ان تعبير لمدا لايتطلب اسم اصلا فيمكن نظريا تعريف واستدعاء تعبير لمدا في نفس السطر :


كود :
            int d = ((Func<int,int>)(x=>x*x))(3);//d=9

هذه كانت نبذة بسيطة عن تعريف تعبير لمدا ، يمكنك ايجاد المزيد هنا :

https://docs.microsoft.com/en-us/dotnet/...nt-lambdas
وهذه مواضيع عن تعبير لمدا ولكنها ل VB.NET
http://vb4arb.com/vb/showthread.php?tid=...ght=lambda
http://vb4arb.com/vb/showthread.php?tid=...ght=lambda

في المشاركة التالية سأعرض استخدامات تعبير لمدا ان شاء الله .
الرد }}}
#2
الاستخدامات

في الواقع يمكنك استخدام تعابير لمبدا في اي مكان اينما اردت ولكن هناك استخدامات عملية لاغنى لاي مبرمج C# عنها مثل :

1. method based linq queries الاستعلامات المبنيه على طرق Linq

لايكاد يخلو اي برنامج لديك من استخدام قاعدة بيانات او List او اي كائن يدعم IEnumerable
تتطلب اغلب اجرائات الاستعلام على الكائنات من النوع IEnumerable مدخل تعبير لمبدا تخبر Linq ماذا تريد ان تفعل تحديدا

بفرض ان لدينا List من نوع string كما يلي :


كود :
 var NumList = new List<int> { 11, 20, 7, 9, 36, 99 };


اذا اردنا ان نحدد العناصر الاكبر من 20 في القائمة ، يمكننا فعل ذلك عن طريق الدالة Where التي تقبل تعبير لمدا يعيد قيمة من نوع bool تحدد الشرط الذي يتم على اسايه اختيار العنصر او لا :

كود :
            var NumsMoreThan20 = NumList.Where(x => x > 20);

            foreach (var i in NumsMoreThan20) 
                textBox1.Text += i.ToString() + ' ';   // 36 99


اذا اردنا تكوين list اخرى قيمة العنصر فيها ضعف قيمته في ال list الحالية ، يمكننا فعل ذلك عن طريق الدالة Select التي تقبل مدخل تعبير لمدا يمثل العلاقة بين العنصر في القائمة الحالية والعنصر في القائمة المراد انشائها : 

كود :
            var NumDublicated = NumList.Select(x => x * 2);

            foreach (var i in NumDublicated)
                textBox1.Text += i.ToString() + ' ';   // 22 40 14 18 72 198 

مثال اخر اذا كان لدينا list من نوع string :


كود :
            var StringList = new List<string> { "mohammed", "saad", "omar", "khaled" };

اذا اردنا ان نحسب عدد الحروف في هذا ال list يمكننا ذلك عن طريق الدالة sum التي تقبل مدخل تعبير لمدا يمثل العلاقة بين العنصر والمطلوب حساب مجموعه :

كود :
            int ListCharCount = StringList.Sum(x => x.Length);

            textBox1.Text = ListCharCount.ToString(); //22

توجد طريقة اخري لاستخدام دالة Select حيث تستخدم تعبير لمدا له مدخلان الاول يمثل العنصر المراد تحويله والثاني يمثل ترتيب العنصر :

الكود التالي يقوم بعمل list اخرى تحوي العناصر الحالية معنونة بترتيبها :

كود :
            var StringListWithNum = StringList.Select((x, index) => $"{index}.{x}");
            
            foreach (var i in StringListWithNum)
                textBox1.Text += i.ToString() + ' ';   // 0.mohammed 1.saad 2.omar 3.khaled 

يتبع ان شاء الله
الرد }}}
#3
2. اسناد الاحداث للكائنات في وقت التشغيل 

اسناد الاحداث للكائنات في وقت التشغيل 

تمكنك تعابير لمدا من ان تقوم باسناد الاحداث للكائنات وقت التشغيل 
اضف button1 الى الفورم ، ثم اضف الكود التالي في حدث load :


كود :
            button1.Click += (S, E) => MessageBox.Show("button1 clicked !");


اضف 5 ازرار مثلا للفورم ،ثم اضف الكود التالي  في حدث load للفورم  لعرض رسالة باسم ال button عند الضغط على اي زر في الفورم :


كود :
          foreach(var b in this.Controls.OfType<Button>())  
                b.Click += 
                    (S, E) => MessageBox.Show($"{b.Name} clicked !");


وكذلك اي حدث يمكن اضافته باستخدام تعبيرات لمدا .

يتبع ان شاء الله
الرد }}}
تم الشكر بواسطة: ابراهيم ايبو , بلدي , بلدي


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  Statements and Expressions Sajad 1 1,922 25-08-17, 05:02 PM
آخر رد: Amir_Alzubidy
Lightbulb طرق إجراء عملية التبديل بين حقلين (Swap Two Variables) عبد الكريم كنعان 2 2,739 31-03-16, 03:40 AM
آخر رد: myalsailamy

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم