امکان استفاده مجدد یا Reusability کدهای نوشته شده :
فرض کنید می خواهیم یک برنامه ای بنویسیم که لیستی را گرفته و آن ها را مرتب کند.
نوع داده این لیست هم برای ما مشخص نیست. خوب اینجا چه کاری می توانیم انجام دهیم؟
شاید در وهله اول این طور به ذهنمان برسد که برای هر نوع داده ای یک تابع مرتب سازی بنویسیم. خوب این می تواند کار ما را راه بیاندازد ولی اگر امکانی وجود داشت که ما می توانستیم یک تابع بنویسیم تا هر لیستی را مرتب کند خیلی راحت تر بودیم. در جواب به این سوالات و حل این مشکل شرکت Microsoft در نسخه .NET 2.0 گزینه Generics را معرفی نمود. با استفاده از این امکان ما در لیست ها محدود به نوع داده نخواهیم بود.
بلکه زمانی که می خواهیم از لیست Generic استفاده کنیم، نوع داده را هم خودمان تعیین می کنیم. به مثال زیر توجه کنید:
<public class GenericClass<T
}
public T [ ] SortListOwn ( T [ ] arr )
}
;return arr
{
{
در این مثال یک متد برای مرتب سازی لیست ایجاد کرده ایم. همان طور که می بینید نوع مشخصی برای آن در نظر گرفته نشده است. زمانی که بخواهیم از این متد و کلاس استفاده کنیم بایستی نوع آن را نیز مشخص نماییم. مانند زیر :
private void Form1_Load ( object sender, EventArgs e )
}
;()<GenericClass< int > x = new GenericClass< int
;int [ ] s = new int [ 2 ]
;s [ 0 ] = 1
;s [ 1 ] = 2
;x. SortListOwn ( s )
{
اگر می خواستیم این کار را با Collectionها انجام دهیم بایستی برای هر نوعی یک متد برای مرتب سازی پیاده سازی می کردیم.
توجه : اگر هنگام تعریف یک Object از نوع کلاس Generic یک نوع داده ای را مشخص نمایید و هنگام ارسال پارامتر نوعی به غیر از نوع مشخص شده ارسال نمایید با خطا مواجه خواهید شد. مثلا نمی توان کد زیر را کامپایل نمود.
[csharp/]
private void Form1_Load(object sender, EventArgs e)
}
;()<GenericClass<int> x = new GenericClass<int
;float[] s = new float[2]
;s[0] = 1f
;s[1] = 2f
;x.SortListOwn(s)
{
[csharp/]
نوع داده امن (Type Safety)
در این مثال می خواهیم لیستی از افراد را با همراه نام و نام خانوادگی داشته باشیم. ببینیم این کار با Collection و Genericها چگونه انجام می شود؟
استفاده از Collection :
;()ArrayList persons = new ArrayList
;Person p1 = new Person { Name = "Ahmad" , Family = "Ghaffari" }
;persons. Add ( p1 )
;Person p2 = new Person { Name = "Farid" , Family = "Taheri" }
;persons. Add ( p2 )
تا اینجای کار هیچ مشکلی وجود ندارد. برنامه کامپایل می شود و هیچ خطایی ندارد. اجازه دهید سطر زیر را هم به کدمان اضافه کنیم.
;persons. Add ( "SanAy Ghaffari" )
برنامه را که اجرا کنیم باز هم خواهیم دید که هیچ خطایی وجود ندارد و برنامه قشنگ کامپایل می شود. شاید بگویید پس مشکل کجاست؟ توضیح خواهم داد. ابتدا کدهای زیر را به ادامه کدها اضافه نمایید :
for ( int i = 0 ; i < persons.Count; i++ )
}
;MessageBox. Show ( ( ( Person ) persons [ i ] ) .Name + " " + ( ( Person ) persons [ i ] ) .Family )
{
حالا برنامه را اجرا کنید. اطلاعات دو شخص تعریف شده را نمایش خواهد داد، ولی زمانی که به آیتم سوم می رسد خطایی مانند زیر روی می دهد:
همان طور که از متن خطا می توان متوجه شد در می یابیم که خطا در زمان تبدیل رشته به کلاس Person روی داده است. چگونه می توان این مشکل را حل کرد؟ راه حل، استفاده از Genericها است. همین مثال را با Genericها انجام می دهیم:
کدهای زیر را در رویداد کلیک یک Button اضافه نمایید :
;()<List<Person> persons = new List<Person
;Person p1 = new Person { Name = "Ahmad" , Family = "Ghaffari" }
;persons. Add ( p1 )
;Person p2 = new Person { Name = "Farid" , Family = "Taheri" }
;persons. Add ( p2 )
اگر برنامه را اجرا کنید هیچ خطایی نخواهد داشت. حالا سطر زیر را به کدها اضافه کنید و دوباره برنامه را اجرا کنید:
;persons. Add ( "SanAy Ghaffari" )
همان طور که می بینید این بار برنامه کامپایل نخواهد شد و خطایی مبنی بر عدم توانایی در تبدیل رشته به Person اتفاق خواهد افتاد. خوب همان طور که می دانید رفع خطاهای زمان کامپایل خیلی راحت تر از خطاهای زمان اجراست و مطمئن خواهیم شد که برنامه ما در هر زمانی کار خود را بدون خطا انجام خواهد داد.
نکته آخر :
با استفاده از عبارت where جلوی کلاس Generic می توانید نوع داده Generic را فیلتر کنید. مثلا اگر بخواهید T شما فقط از نوع کلاس Person باشد به شکل زیر عمل نمایید :
public class GenericClass<T> where T : Person
در این جا باید توجه داشته باشید که نوع ورودی شما Person و هر کلاسی که از Person ارث بری کرده باشد می تواند به عنوان ورودی به این کلاس ارسال گردد.
پس مزایای کلی استفاده از Genericها عبارتند از :
۱٫ کدهایمان ساده تر خواهد شد.
۲٫ حجم کدنویسی پایین خواهد آمد.
۳٫ قابلیت استفاده مجدد از کدهایمان بالا خواهد رفت.
۴٫ Performance اجرای برنامه بالا خواهد رفت. اگر در مثال لیست اشخاص با استفاده از Collectionها دقت کنید، زمانی که ما خواستیم تا اطلاعات اشخاص را نمایش دهیم مجبور شدیم تا یک تبدیل نوع (Type Cast) انجام دهیم. هنگام استفاده از Genericها این تبدیل از کد ما حذف شد. بنابراین مدت زمانی که برای تبدیل نوع استفاده می شود نیز حذف خواهد شد.
منبع:nikamooz