تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
[مقال] مفهوم Generics بشكل مبسط
#1
مفهوم Generics بشكل مبسط

بسم الله الرحمن الرحيم , و السلام عليكم و رحمة الله و بركاته.

اطرح هذا الموضوع لكشف الغطاء عن مفهوم Generics  بشكل مبسط وبعيداً عن التعقيد , أي مجرد افكار بسيطة ليتم استيعابها من الذين لم يستوعبوها.
الفكرة من هذا المفهوم بأبسط تفسيراتها جاءت من مفهوم اعادة تحميل الدالة بشكل زائد او ما يسمى (OverLoading).(اعادة تعريف ,اعادة قيادة)
فمثلاً لو كان لديك دالة تقوم بعرض رسالة و هذه الدالة تأخذ وسيطة نصية (نص الرسالة)و من ثم تقوم بعرضها.
مثال1:
PHP كود :
Public Shared Sub ShowMsg(ByVal x As String)
 
   MsgBox(x)
End Sub 

و اردت ان تجعل الدالة اكثر تعميما بحيث ان تكون الوسيطة هذه المرة رقمية,و في مرة اخرى نوع اخر ,هذا ما يسمى بإعادة القيادة.
PHP كود :
Public Shared Sub ShowMsg(ByVal x As Integer)
 
   MsgBox(x)
End Sub
 
Public Shared Sub ShowMsg(ByVal x As Long)
 
   MsgBox(x)
End Sub 

لاحظ عند استدعائك للدالة ستتوفر لديك 3 نسخ محملة بشكل متتالي كل واحدة لها نوع من البيانات.
انا استخدمت هذه الدالة بشكلها المبسط للتسهيل فقط , اذ ان عرض رسالة لا يحتاج لمثل هذا التعقيد , ولكن للتوضيح فقط...؟

الان ماذا لو اردت ان توسع الدالة لتقوم بعرض انواع اضافية غير الانواع السابقة ,اكيد ستكتب دالة جديدة فيها النوع الجديد ,و ماذا لو استمرت الحاجة الى انواع جديدة..؟
اذاً انت محتاج الى حل يمكنك من استخدامها مع أي نوع تريد من دون الدخول و اضافة دوال جديدة كل مرة.
لهذا جاء مفهوم الــ Generics ليريحك من هذا العناء.
يخبرك الـ Generic انه بإمكانك ان تعرف دالة تأخذ وسائط مجهولة النوع و من ثم عن استدعائك لها تعوض النوع في مكان المجاهيل و تنتهي المشكلة...؟
شكل الدالة
PHP كود :
Public Shared Sub ShowMsg(Of T)(ByVal x As T)
 
    MsgBox(x)
End Sub 

و شرحها بكل بساطة :المتغيرات ستكون من النوع T المجهول , و عند حاجتي لاستدعائها ساضع مكان T الاولى النوع ومن ثم مكان T الثانية قيمة النوع, فلو اردت ان اعرض ارقام من النوع Integer ستصبح الدالةعند الاستدعاء:
PHP كود :
ShowMsg(Of Integer)(25215
سهلة و مريحة و وفرت علي الكثير من الوقت.
 

 
لم ينتهي الكلام هنا , اذ ان مفهوم Generics يمكن تطبيقه على الكلاسات و التراكيب ايضاً
بنفس الطريقة تماما , و ممكن ان تكون الحقول داخلها من النوع T و كذلك الدوال و الخصائص.
 

 
مفهوم Generic Collection


هذا المفهوم يمكن شرحه كالتالي:
تخيل ان لديك اكثر من كلاس و كل كلاس يخص جدول محدد و كل الكلاسات هذه تشترك في نوع معين من الوظائف مثل (الاضافة و الحذف و التعديل و البحث... و غيرها),فبدل ان تكتب وظائف لكل كلاس على حدا , (مثل كلاس الطلاب ,و كلاس الموظفين,و كلاس العملاء..الخ)
 
هنا جاء Generic Collection كحل لهذا الموضوع فكما سبق كل ما عليك هو الاعتماد على الانواع المجهولة و عند الحاجة للاستدعاء تغير المجهول بنوع البيانات الذي تريد التعامل معه.
انظر لهذا Collection
PHP كود :
Public Class My_Collection(Of T)
 
 
   Private List As New List(Of T)()
 
 
   Public Function GetItem(ByVal i As Integer) As T
        Return 
List(i)
 
   End Function
 
 
   Public Sub InsertItem(ByVal p As T)
 
       List.Add(p)
 
   End Sub
 
    Public Sub ClearList
()
 
       List.Clear()
 
   End Sub
 
 
    Public 
Function GetCount()
 
       Return List.Count
    End 
Function
 
 
   Public Sub InsertAt(ByVal index As IntegerByVal item As T)
 
       List.Insert(indexitem)
 
   End Sub
 
    Public 
Function Contains(ByVal item As T) As Boolean
        Return 
List.Contains(item)
 
   End Function
 
 
 
   Public Function IndexOf(ByVal item As T) As Integer
        Return 
List.IndexOf(item)
 
   End Function
 
 
   Public Sub Remove(ByVal item As T)
 
       List.Remove(item)
 
   End Sub
 
 
End 
Class 
 

فهو يستقبل أي كلاس و يمكنك الاستفادة من وظائفه المجهولة و غير المجهولة لتطبيق العمليات على الكلاس المراد تمريره
 




 
سأفرض ان لدي جدول للعملاء و يحتوي على حقلين المعرف و الاسم.
سأعرف كلاس موافق له يحتوي على الحقلين السابقين و سأعرف له Constructor.
بنية الكلاس :
PHP كود :
Public Class Customer
    Public Sub 
New(_id As Integer_name As String)
 
       ID _id
        Name 
_name
    End Sub
 
    Private m_id 
As Integer
 
    Public Property ID
() As Integer
        Get
            Return m_id
        End Get
        Set
            m_id 
Value
        End Set
    End Property
 
    Private m_name 
As String
 
    Public Property Name
() As String
        Get
            Return m_name
        End Get
        Set
            m_name 
Value
        End Set
    End Property
End 
Class 


الان و وفق الكلاس السابق يمكنني انشاء عملاء جدد:
PHP كود :
Dim Fesal As New Customer(1"fesal"


و بالاستفادة من Collection السابق لدي وظائف جاهزة فقط امرر الكلاس كوسيطة و استفيد من الوظائف.
PHP كود :
Dim Fesal As New Customer(1"fesal")
Dim Nader As New Customer(2"nader")
Dim Sosan As New Customer(3"sosan")
 
Dim CustCollection As New My_Collection(Of Customer)()
 
CustCollection.InsertItem(Fesal)
CustCollection.InsertItem(Nader)
CustCollection.InsertAt(2,Sosan)
 
MsgBox(CustCollection.Contains(Fesal)) 
هل اتضحت لديك الصور الان...
 



مفهوم  T As
يقابلها في C# مفهوم T Where


من اسمه هو شرط للعناصر التي من النوع T ,بمعنى اخر لا تقبل سوى الانواع التي تأتي بعد كلمة Where او As مثل ان تكون الانواع مثل Class,Integer... او أي نوع يأتي بعد الحرف T مقبولة في التعامل و بمعنى ابسط يمكن تمرير الانواع السابقة كوسائط للـ Collection فقط
مثال1:


where T : class
من النوع RefernceType
 ــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــ
Where T :Struct
من النوع ValueTpe
 ـــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــ
Where T : New
يجب ان يحتوي على Constructor
 ____________________________________________
Where T :ClassName
يجب ان يكون مشتق من كلاس اخر
 ____________________________________________
Where T :InterFaceName
يجب ان يطبق أي InterFace
___________________________________________________
 

و بالتطبيق على Collection السابق لدينا ليقبل فقط Class  مع Constructor .
سنكتبه كما يلي :
PHP كود :
Public Class My_Collection(Of T As {Class, New}) 
في #C سنكتب مثل هذا
PHP كود :
public class My_Collection <Twhere T : class, new() 



و اخيراً يبقى سؤال ...؟
هل تقبل الـ Collection اكثر من وسيطة مجهول وهل  استطيع ان احدد الانواع لكل وسيطة.
 
نعم تستطيع ذلك و بكل سهولة كما تعمل مع أي دالة تستقبل وسائط..
مثال:
PHP كود :
Public Class My_Collection2(Of T As {Class, New}, As {Structure})
 
End Class 
 
و مع Generic ايضاً
مثال مع اجراء:
PHP كود :
Private Sub TransFer(Of T)(data As List(Of T), As Integer)
 
End Sub
 
 
Private Sub Export(Of T)(data As List(Of T), ParamArray parameters As String())
 
End Sub 
 

كما ترى الوسيطة الاولى مجهولة و الثانية معلومة النوع.
 
ان شاء الله تكون الامور تكشفت عن مفهوم Generics ولو بشكل بسيط , و الله الموفق.
 
اللهم لك الحمد كما ينبغي لجلال وجهك و عظيم سلطانك
في حل و ترحال
الرد
#2
الله يكرمك يا ابو ليلي
والله كتر خيرك في مواضيعك الجميلة دي
جزاك الله خيرا
الرد
تم الشكر بواسطة: ابو ليلى , ابو تالا
#3
بارك الله فيك يا ابو ليلى

موضوع موجز وشامل في نفس الوقت عن الـ Generic

نعم انها قوة الـ OOP Smile
الرد
تم الشكر بواسطة: ابو ليلى , Fantastico
#4
الله يرحم والديك ويجزيك بالخير
<يعطيك العافية>
الرد
تم الشكر بواسطة: ابو ليلى



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


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