جنريک ها به منظور ايجاد قابليتهاي جديدي همچون حذف نياز به Casting يا تخصيص نوع، افزايش ايمني متغييرها، کاهش اثر Boxing و همچنين براي آسانتر کردن ايجاد کلاسها و متدهاي عمومي (Generalized) به 2.0 C# اضافه شدند. به عبارت ديگر اين قابليت جديد به شما اجازه مي دهد تعريف دقيق يک نوع داده (datatype) را تا زمان ايجاد يک نمونه از نوع جنريک به تعويق بيندازيد. به اين ترتيب يکي از بزرگترين مزاياي استفاده از جنريکها بالاتر بردن ميزان بازدهي برنامه است.
کلاسهاي جنريک و متدهاي آن پارامترهاي نوعي (Type Parameter) در خود مي پذيرد که مشخص کننده نوع اشيايي است که در حال کار با آنها مي باشد. در اين قسمت با يک مثال به طرح مشکل و راه حل آن با استفاده از جنريکها مي پردازيم.
به قطعه کد زير توجه کنيد (مشکل):
public class Customer
{
public void AddDetailItem( object detailItem )
{
if (detailItem is OrderItem)
PerformAction( (OrderItem)detailItem );
if (detailItem is CalendarEvent)
AddCalendarEvent( (CalendarEvent)detailItem);
...
}
}
|
همانگونه که در بالا مي بينيد، با قرار دادن ifهاي متعدد ، سعي شده که کارآيي هاي مختلف و مورد نظر از برنامه گرفته شود، در حالي که به سادگي مي توان با استفاده از پارامترهاي نوعي و جنريکها کاربرد دقيق کلاس Customer را در زمان نمونه گيري از کلاس انجام داد: (راه حل)
public class Customer<T> { public void AddDetailItem( T detailItem ) { ... } } |
به عبارت ديگر پارامتر واقعي يک کلاس جنريک در هنگام نمونه گيري از آن کلاس ايجاد مي گردد:
Customer<OrderItem> customer=new Customer<OrderItem>();
|
از ديگر خواص جالب توجه کلاسهاي جنريک اين است که مي توان نوع پارامترهايي را که به کلاس ارسال مي شوند، محدود نمود. به اين منظور از کليد واژه where استفاده مي شود که به دنبال آن نوعهاي قابل قبول براي کلاس تعريف مي گردند. به عنوان نمونه در مثال زير پارامتر نوعي T بايد اينترفيسهاي ISerializable و IComparable را پياده سازي نمايد:
public class myCollection<T> where T: ISerializable, T: IComparable
|
به طور کلي سه نوع محدوديت که بايد به عنوان محدويتهاي خاص از آنها نام برد عبارتند از:
class: نشان مي دهد که پارامتر بايد از نوع Reference يا Reference Type باشد.
struct: پارامتر بايد از نوع Value type باشد.
()new: پارامتر بايد داراي يک سازنده يا constructor بدون پارمتر ورودي باشد.
در قسمت بعدي اين مقاله، به توضيحات بيشتري در خصوص اين مبحث پرداخته شده و مثالي نيز در اين مورد ارائه مي گردد.