تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
7.0 Pattern Matching in C#.NET
#1
بسم الله الرحمن الرحيم
((رب اشرح لي صدري ويسر لي امري واحلل عقدة من لساني يفقهوا قولي))

7.0 Pattern Matching in C#.NET



هذه الخاصية كانت موجودة في لغة C# في الاصدارات السابقة وجرى تطويرها في الاصدار الاخير من اللغة (C# 7.0) حيث اصبح بالامكان اسناد قيمة المتغير الى المتغير الجديد  في حال كان من نفس النوع.


يمكن استخدام هذه الخاصية مع (is expression) و (switch statement) حيث تم تطوير (switch statement) في الاصدار C# 7.0 ليقبل الانواع الاخرى ايضا ولم يبقى محددا للـ Value Types بل اصبح بامكانك استخدام الـ Reference Type ايضا. سنوضح ذلك باذن الله في درس اخر.


لنوضح خاصية الــ Pattern Matching بهذا المثال :

لو كان لدينا كلاس أب باسم Person يحتوي على الخصائص التالية (الاسم، العمل، الراتب) ويحتوي على دالة باسم (PrintInfo):

PHP كود :
public abstract class Person
    
{
 
       public string Fullname getset; }
 
       public string Job getset; }
 
       public double Salary getset; }
 
       public abstract void PrintInfo(); // must implemented in derived classes
 
   

ولدينا الكلاسات التالية (Employee, Player) ترث من الكلاس Person:
PHP كود :
public class Employee Person
    
{
 
       public override void PrintInfo() => Console.WriteLine($"{Fullname} he is {Job} and his salary is {Salary}");
 
   }

 
   public class Player Person
    
{
 
       public override void PrintInfo() => Console.WriteLine($"{Fullname} he is {Job} player and his salary is {Salary}");
 
   

الان لو عملنا قائمة (List) من الكلاس Person وقمنا بملئ المعلومات بالشكل التالي:
PHP كود :
var personList = new List<Person>
 
           {
 
               new Employee
                
{
 
                   Fullname="Ali Ahmed",
 
                   Job="Teacher",
 
                   Salary=3000
                
},
 
               new Employee
                
{
 
                   Fullname="Ameer Sami",
 
                   Job="Programmer",
 
                   Salary=45588
                
},
 
               new Player
                
{
 
                   Fullname="Hameed Omer",
 
                   Job="Tennis",
 
                   Salary=330
                
},
 
               new Player
                
{
 
                   Fullname="Hassan HH",
 
                   Job="basketball",
 
                   Salary=556
                
},
 
               new Player
                
{
 
                   Fullname="Jameel hh",
 
                   Job="Volleyball",
 
                   Salary=667
                
}
 
           }; 

كما تلاحظ أنه بامكاننا اضافة معلومات كلاسات الابناء لانها ترث من الكلاس Person وبامكاننا استخدام الخصائص (Properties) الموجودة في الكلاس الأب بشكل طبيعي.

هنا نطرح السؤال التالي: قم بكتابة كود برمجي لايجاد الراتب الكلي لجميع الموظفين واللاعبين في القائمة <List<Person.

كما ترى اخي العزيز أن القائمة فيها نوعين من الـ Type وهي Employee و Player. 

طيب كيف اقوم بالتمييز بينهما بحيث اقوم بحساب الرواتب للموظفين واللاعبين بشكل منفصل؟

الجواب هو: باستخدام Pattern Matching.

طيب لنرى الطريقة القديمة قبل استخدام الخاصية الجديد:
PHP كود :
// d is for double
var totalEmpSalary 0d;
 
           var totalPlayerSalary 0d;
 
           foreach (var item in personList)
 
           {
 
               // old way
 
               if (item is Employee)
 
               {
 
                   var emp item as Employee// or var emp = (Employee)item;
 
                   totalEmpSalary += emp.Salary;
 
               }
 
               else if (item is Player)
 
               {
 
                   var player item as Player// or var player = (Player)item;
 
                   totalPlayerSalary += player.Salary;
 
               }
 

لنرى الان الطريقة الجديدة واترك لكم ملاحظة الفرق بالكود:
PHP كود :
// d is for double
 
           var totalEmpSalary 0d;
 
           var totalPlayerSalary 0d;
 
           foreach (var item in personList)
 
           {
 
             
                
// new way using pattern matching
 
               if (item is Employee emp)
 
                   totalEmpSalary += emp.Salary;
 
               else if (item is Player player)
 
                   totalPlayerSalary += player.Salary;
 
           }

 
           Console.WriteLine($"Total salary of  employees : { totalEmpSalary}");
 
           Console.WriteLine($"Total salary of  players : { totalPlayerSalary}");

 
           Console.ReadKey(); 

الاختلاف بين الكودين هو امكانية تعريف متغير اثناء التحقق من نوعية الـType وفي حال تحقق الشرط يتم اسناد القيمة الى المتغير في نفس السطر. دون الحاجة الى انشاء متغير وعمل casting لها كما في الكود السابق.

فعمل الـ is هنا كالتالي: هل item  هو Employee اذا نعم اسند قيمة الـitem الى المتغير الجديد emp في نفس السطر وهكذا مع الـPlayer.


لنستخدم الكود الثاني مع الـswitch: سأكتب في جزء Pattern Matching داخل الـforeach loop:
PHP كود :
switch (item)
 
               {
 
                   case Employee emp:
 
                       totalEmpSalary += emp.Salary;
 
                       break;
 
                   case Player player:
 
                       totalPlayerSalary += player.Salary;
 
                       break;
 
               


كما قلت سنتناول switch في الـ C# 7.0 في درس آخر باذن الله.

لا تنسونا و والديّ من صالح دعواتكم.
الرد }}}
تم الشكر بواسطة: محمد كريّم
#2
شرح رائع استمر
الرد }}}
تم الشكر بواسطة: Sajad


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


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