المساعد الشخصي الرقمي

مشاهدة النسخة كاملة : الدرس الواحد والثلاثون : ال Generic دورة .net 2008


khaledbelal
02-25-2010, 02:30 PM
بسم الله الرحمن الرحيم .
السلام عليكم ورحمة الله وبركاته .

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

C#:

public static void print(int x)
{
Console.WriteLine("Print As Integer {0}", x);
}
public static void print(long x)
{
Console.WriteLine("Print As Long {0}", x);
}
public static void print(string x)
{
Console.WriteLine("Print As String {0}",x);
}


vb.net:


Public Shared Sub print(ByVal x As Integer)
Console.WriteLine("Print As Integer {0}", x)
End Sub
Public Shared Sub print(ByVal x As Long)
Console.WriteLine("Print As Long {0}", x)
End Sub
Public Shared Sub print(ByVal x As String)
Console.WriteLine("Print As String {0}", x)
End Sub


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

print("Ahmed");
print(12);
print(1000000000000);


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

http://vb4arab.com/vb/uploaded/3/01207649506.jpg

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

C#:

public static void print<T>(T x)
{
Console.WriteLine("Print As {0}: {1}",typeof(T), x);

}


vb.net:

Public Shared Sub print(Of T)(ByVal x As T)
Console.WriteLine("Print As {0}: {1}", GetType(T), x)

End Sub

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

http://vb4arab.com/vb/uploaded/3/11207649506.jpg

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

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")

هناك الكثير من التطبيقات على هذا المفهوم ، نواصل في الدرس القادم إن شاء الله .

Generic Collection :

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

C#:

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

vb.net:

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

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

MyCollection<Car> myCars = new MyCollection<Car>();
myCars.AddItem(temp);
MyCollection<Employee> myCars = new MyCollection<Employee>();
myCars.AddItem(tempEmployee);

vb.net:

Dim myCars As New MyCollection(Of Car)()
myCars.AddItem(temp)
Dim myCars As New MyCollection(Of Employee)()
myCars.AddItem(tempEmployee)

أو حتى ارقام :
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 والتي سنتحدث عنها في الدرس القادم .

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:

Public Class Example(Of T As {Class, IComparable, New})


هذا يعني ان 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 بدلاً من جعلها مفتوحة للجميع .

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

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

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