تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
الدرس الواحد والثلاثون - ال Generic
#1
كاتب الموضوع : أحمد جمال

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

نواصل في هذا الدرس مع واحدة من التطورات الجديدة مع .net framework 2.0 ، هي ال generics لتعطي بعداً جديداً لمفهوم ال overloading ، لنفترض مثالاً ما للطباعة بالشكل التالي :

C#:

كود :
[FONT=Tahoma]public static void print(int x)
{
Console.WriteLine("Print As Integer {0}", x);
}[/FONT]
[FONT=Tahoma]public static void print(long x)
{
Console.WriteLine("Print As Long {0}", x);
}[/FONT]
[FONT=Tahoma]public static void print(string x)
{
Console.WriteLine("Print As String {0}",x);
}[/FONT]


vb.net:


كود :
[FONT=Tahoma]Public Shared Sub print(ByVal x As Integer)
Console.WriteLine("Print As Integer {0}", x)
End Sub [/FONT]
[FONT=Tahoma]Public Shared Sub print(ByVal x As Long)
Console.WriteLine("Print As Long {0}", x)
End Sub [/FONT]
[FONT=Tahoma]Public Shared Sub print(ByVal x As String)
Console.WriteLine("Print As String {0}", x)
End Sub [/FONT]


الكود كما هو واضح قام بعمل ثلاث دوال بنفس الاسم لاستقبال بارميترات مختلفة ، وهكذا تجد انك تستطيع في الكود استدعاء الدالة الطباعة للارقام او لل longs او للنصوص ، جرب عدة عمليات لطباعة انواع مختلفة وشاهد جملة الطباعة ، على سبيل المثال الأوامر التالية :

كود :
[FONT=Tahoma]print("Ahmed");
print(12);
print(1000000000000);[/FONT]


سيكون ناتج الطباعة بالشكل التالي :


ال Generics ستغير المفهوم نوعاً ، حيث ان بامكانك الآن تعريف دالة لا تستقبل نوعاً معيناً من المتغيرات ، بل هي تستقبل <T> وتتعامل معه على هذا الاساس ، لذا قد نستطيع افتراض الدوال الثلاث السابقة بالشكل التالي :

C#:

كود :
[FONT=Tahoma]public static void print<T>(T x)
{
Console.WriteLine("Print As {0}: {1}",typeof(T), x);[/FONT]

[FONT=Tahoma]}[/FONT]


vb.net:

كود :
[FONT=Tahoma]Public Shared Sub print(Of T)(ByVal x As T)
Console.WriteLine("Print As {0}: {1}", GetType(T), x)

End Sub [/FONT]

والآن في حالة تطبيقنا لنفس المثال السابق ، سوف يكون الناتج كالتالي :



كانت هذه مقدمة سريعة لل Generics ، نواصل في دروس قادمة التعرف على نقاط أخرى حول هذا الموضوع ، لا تنس ان هذا درس من سلسلة دروس نطبق فيها مبادئ تتعلق ب LINQ حيث ان كل ما يتعلق بالانواع المجهولة والدوال المجهولة ... الخ يتعلق بشكل أو بآخر بال LINQ .
}}}
تم الشكر بواسطة:
#2
Structure and Class Generics :

في الدرس السابق تعرفنا على ال methods التي تطبق ال Generics ، ايضاً ال Classes وال Structs يمكنها تطبيق هذا المفهوم لبعض البيانات بها ، سنفترض مثال ال class وما ينطبق على ال class ينطبق على ال struct .

لنفترض كلاس يحتوي على البضائع ، وحيث ان لدينا نوعين من البضائع يحتوي النوع الأول على الاسم وهي تلك البضائع التي يتم تصنيعها في المحل ( انوع من الجبن او الزبادي ) وبضائع أخرى جاهزة تحتوي على الباركود ، بهذه الطريقة نسنتج ان حقل Identify قد يحتوي على اسم في بعض البضائع ورقم في بضائع أخرى .

الحل التقليدي كان ليعتبر وجود كلاسين منفصلين ، أو في أحسن الظروف وضع قيمة منطقية لتحديد اذا ما كنت ساستخدم حقل ال name ام حقل ال numbner ، لكن مع ال Generics تم تغيير هذا المفهوم ، في هذه الحالة سيصبح الكلاس بالشكل التالي :
c#:


كود :
public class product<T>
{
private T Identify;
public product(T val)
{
Identify = val;
Console.WriteLine(Identify);
}
}
vb.net:

كود :
Public Class product(Of T)
Private Identify As T

Public Sub New(ByVal val As T)
Identify = val
Console.WriteLine(Identify)
End Sub

End Class
والآن يمكنني تعريف كائن من النوع الأول بالشكل التالي :
C#:

كود :
product<int> prd = new product<int>(1001);
vb.net:

كود :
Dim prd As New product(Of Integer)(1001)
أو من النوع الثاني بالشكل التالي :

C#:

كود :
product<string> prd2 = new product<string>("Some Product");
vb.net:

كود :
Dim prd2 As New product(Of String)("Some Product")
هناك الكثير من التطبيقات على هذا المفهوم ، نواصل في الدرس القادم إن شاء الله .
}}}
تم الشكر بواسطة:
#3
Generic Collection :

كما تعرفنا في الدرس السابق ان بامكاننا عمل Generic Class ، اصبح الدور الآن على عمل Generic Collection ، سنقوم بعمل كلاس يستقبل عدة كلاسات ويقوم بعدة عمليات مثل Add,Delete ... etc ، كما تعلمنا سابقاً ، هذا مثال على Collection ما :

C#:


كود :
[FONT=Tahoma]public class MyCollection<T>[/FONT]
[FONT=Tahoma]{[/FONT]
[FONT=Tahoma]private List<T> myList = new List<T>();[/FONT]
[FONT=Tahoma]public T GetItem(int pos)[/FONT]
[FONT=Tahoma]{[/FONT]
[FONT=Tahoma]return myList[pos]; [/FONT]
[FONT=Tahoma]}[/FONT]
[FONT=Tahoma]public void AddItem(T it)[/FONT]
[FONT=Tahoma]{[/FONT]
[FONT=Tahoma]myList.Add(c); [/FONT]
[FONT=Tahoma]}[/FONT]
[FONT=Tahoma]public void ClearCars()[/FONT]
[FONT=Tahoma]{[/FONT]
[FONT=Tahoma]myList.Clear(); [/FONT]
[FONT=Tahoma]}[/FONT]
[FONT=Tahoma]}[/FONT]

vb.net:

كود :
[FONT=Tahoma]Public Class MyCollection(Of T)
Private myList As New List(Of T)()
Public Function GetItem(ByVal pos As Integer) As T
Return myList(pos)
End Function
Public Sub AddItem(ByVal it As T)
myList.Add(c)
End Sub
Public Sub ClearCars()
myList.Clear()
End Sub
End Class [/FONT]

طبعاً بامكانك اضافة الكثير من الخصائص وربما بعض الخصائص الغير متوفرة اصلاً للبحث وخلافه ، هذا ما يسمى بال Generic Collection حيث يمكن في مراحل لاحقة الاعتماد عليه بدل ال Colelctions العادية حيث يمكن ان يستقبل Car او Employee .... إلى غير ذلك من الخيارات ، بالشكل التالي مثلاً :

C#:

كود :
[FONT=Tahoma]MyCollection<Car> myCars = new MyCollection<Car>();
myCars.AddItem(temp);
MyCollection<Employee> myCars = new MyCollection<Employee>();
myCars.AddItem(tempEmployee);[/FONT]

vb.net:

كود :
[FONT=Tahoma]Dim myCars As New MyCollection(Of Car)()
myCars.AddItem(temp)
Dim myCars As New MyCollection(Of Employee)()
myCars.AddItem(tempEmployee) [/FONT]

أو حتى ارقام :

C#:

كود :
MyCollection<int> myCars = new MyCollection<int>();
myCars.AddItem(12);

vb.net:

كود :
Dim myCars As New MyCollection(Of Integer)()
myCars.AddItem(12)


هنا ظهرت لنا مشكلة تتعلق بكون ال Generic Collection الخاص بنا يحتوي على خصائص مثل .name لعرضها ، وهذا ما لا يتوفر مثلاً لكل الكلاسات او للارقام مثلاً ، من هنا جاءت لنا الكلمة المحجوزة Where والتي سنتحدث عنها في الدرس القادم .
}}}
تم الشكر بواسطة:
#4
Where T :

يتيح لنا هذا الشرط في عمل ال Generic Collection ان لا نقبل سوى بعض الفئات ، يمكننا وضع الشروط بأحد الطرق التالية :

where T : struct
بحيث لا يقبل سوى متغيرات من النوع ValueTpe .


where T : class
لا يقبل سوى من النوع RefernceType .


where T : new()
لا بد ان يحتوي على Constructor .


where T : classname
where T : Iinterfacename

لا بد ان يكون مشتق من class معين او يطبق interface معين .

بهذه الطريقة يمكننا دمج عدة شروط مع بعضها ، لنرى المثال التالي سوية :
C#:

كود :
public class Example <T> where T : class, IComparable, new()

vb.net:

كود :
[FONT=Tahoma]Public Class Example(Of T As {Class, IComparable, New}) [/FONT]


هذا يعني ان T لا بد ان تكون refernce ، تطبق الواجهة IComparable وتحتوي على Constructor .
ايضاً المثال التالي :
c#:

كود :
public class Example<K, T> where K : class, new()
where T : IComparable<T>

vb.net:

كود :
Public Class Example(Of K As {Class, New}, T As IComparable(Of T))

هذا يعني ان T لا بد ان تكون Refernce ولها constructor فيما k لا بد ان تطبق الواجهة IComparable .

والآن ، اصبح بامكانك التحكم بعض الشيء في T بدلاً من جعلها مفتوحة للجميع .
}}}
تم الشكر بواسطة:
#5
آخر نقطة انبه عليها في هذا الدرس ، انه وتحت مجال الاسماء System.Collections.Generic تجد العديد من ال Collections التي تعاملنا معها سابقاً مثل ال Queue او ال Stack ، ولكن بدلاً من تعاملها مع object فهي تطبق مبادئ ال Generics باستقبالها T .

الآن استطيع ان ازعم انني غطيت بعض النقاط الاساسية في عالم ال Generics ، اتمنى ان اكون قد قدمت شيئاً جديداً .

والله الموفق ...
والسلام عليكم ورحمة الله وبركاته .
}}}
تم الشكر بواسطة:



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


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