PDA

View Full Version : آموزش کامل جنریک ها (توابع، کلاس ها و ...)



pooria2c
پنج شنبه 10 اسفند 1391, 16:49 عصر
با عرض سلام و خسته نباشید، خدمت دوستان عزیز و مدیران محترم وب سایت،


توی وب درباره جنریک ها زیاد بحث نشده و اگه دوستان استقبال کنند، یک تاپیک کامل رو درباره جنریک ها (کلاس ها، توابع، اینترفیس ها و ...) شروع کنم. البته اگه دوستان موافق باشند.

منتظر نظراتتون هستم.

pooria2c
پنج شنبه 10 اسفند 1391, 20:58 عصر
جنریک ها رو میشه به صورت توابع سربارگذاری شده در نظر گرفت به طوری که اصلاً چنین پیاده سازی رو ندارند اما مفهومی مشابه رو ارائه می کند.

این مثال رو در نظر بگیرید:
شما می خواهید تابعی داشته باشید که انواع داده int، double، float و ... رو با هم جا به جا کنید.

اگر بخواهید این عمل را با توابع سربارگذاری شده انجام بدهید باید توابع رو به صورت زیر تعریف کنید.

public void Swap(ref int a, ref int b)
{int tmp;
tmp = a;
a = b;
b = tmp;
}

public void Swap(ref double a, ref double b)
{double tmp;
tmp = a;
a = b;
b = tmp;
}

حال اگر شما توابع رو به صورت :
Swap(12, 14);
و یا
Swap(12.5, 14.5);

فراخوانی کنید، خود کامپایلر متوجه می شود که کدام تابع را بر اساس نیاز باید فراخوانی کند.

حالا شما فکر کنید که مثلاً یه تابع که 100 بار سربارگذاری شده داریم!!! چه فاجعه ای رخ می ده (از لحاظ کدی که نوشته می شه)!! :عصبانی++:


خوب حالا به راحتی می تونیم با استفاده از جنریک ها در اینجا (توابع جنریک) استفاده کنیم و از تکرار کد جلوگیری کنیم.

نمونه کد :

public static void Swap<T>(ref T a, ref T b)
{
T tmp;

tmp = a;
a = b;
b = tmp;
}

که هنگام فراخوانی باید به صورت زیر عمل کرد:


static void Main(string[] args)
{
int ia = 12,
ib = 14;

Console.WriteLine("Before Swap<int>...");
Console.WriteLine("{0}, {1}", ia, ib);

Swap<int>(ref ia, ref ib);

Console.WriteLine("After Swap<int>...");
Console.WriteLine("{0}, {1}", ia, ib);

Console.WriteLine();

double da = 12.5,
db = 14.5;

Console.WriteLine("Before Swap<double>...");
Console.WriteLine("{0}, {1}", da, db);

Swap<double>(ref da, ref db);

Console.WriteLine("After Swap<double>...");
Console.WriteLine("{0}, {1}", da, db);




Console.ReadLine();
}




خوب این مقدمه ای از جنریک ها بود، انشا الله در پست های بعدی درباره کلاس ها، اینترفیس ها، ساختار ها، Delegate ها و هر چیزی دیگه ای که می تونیم به صورت جنریک پیاده سازی کنیم توضیح داده خواهد شد و مثال هایی رو خواهیم زد تا فهم مطلب آسان تر باشد.



با تشکر

pooria2c
جمعه 11 اسفند 1391, 11:28 صبح
خوب دوستان در این پست می خوام درباره کلاس های جنریک توضیحاتی رو خدمتتون ارائه بدم:


کلاس های جنریک :

کلاس های جنریک کلاس هایی هستند که می توان انواع داده از نوع های معمولی تا نوع هایی که بوسیله کاربر تولید میشه (مثل کلاس ها، ساختارها و ...) رو به صورت پارامتریک بهشون ارسال کرد.

مثل :



public class Test<T>
{
public void DataType()
{
Type type = typeof(T);

Console.WriteLine("Type is : {0}", type);
}
}




که در این مثال به جای T از نوع های داده ای مثل int, double و یا نوع هایی که به وسیله کاربران تولید شده اند استفاده میشوند
و به صورت زیر به کار می رود :



static void Main(string[] args)
{
Test<Int32> objInt32 = new Test<Int32>();
objInt32.DataType();

Test<Double> objDouble = new Test<Double>();
objDouble.DataType();


Console.ReadLine();
}




و نتیجه زیر حاصل می شود :

Type is : System.Int32

Type is : System.Double


یکی از کلاس های جنریک که توی ویژوال استادیو موجوده، کلاس List<T> هست، کاربرد این کلاس به صورت زیره:



static void Main(string[] args)
{
List<int> objInt = new List<int>();

objInt.Add(1);
objInt.Add(2);
objInt.Add(3);
objInt.Add(4);
objInt.Add(5);


int sum = 0;

foreach (int item in objInt)
{
Console.WriteLine(item);

sum += item;
}

Console.WriteLine("Sum is : {0}", sum);


Console.ReadLine();
}








و خروجی آن به صورت زیر است :

1
2
3
4
5
Sum is : 15




>> خوب حالا شاید این نکته توی ذهنتون اومده باشه که "چرا از کلاس ArrayList (که یک کلاس غیر جنریک هست) استفاده نکردیم؟؟؟!!؟!؟!! اونم که دقیقاً همین کار و انجام می ده!!!! این کلاس میتونه هر نوع داده ای رو تو خودش ذخیره کنه"

درسته، دقیقاً نکته همین جاست، توی این کلاس شما می تونید هر نوع داده ای رو ذخیره کنید با این تفاوت که Type Safe نیست،

>> یعنی چی ؟؟

یعنی اینکه قبل از استفاده از عناصر موجود در ArrayList باید عملیات Casting و یا امثال آن رو انجام بدید.

مثال زیر را در نظر بگیرید :


static void Main(string[] args)
{
ArrayList list = new ArrayList();

// string type
list.Add("hello");
list.Add("C#‎");
// integer type
list.Add(12);
list.Add(13);
list.Add(20);
// double type
list.Add(12.5);
list.Add(16.5);

foreach (var item in list)
{
Console.WriteLine(item);
}


Console.ReadLine();
}



در این مثال یک ArrayList تعریف شده که چند عضو داره و هر عضو اون نوع های متفاوتی داره، حالا ما می خواهیم از توی این لیست اون هایی که مقادیر عددی صحیح داره رو جمع کنیم !
پس باید عملیات Casting رو انجام بدیم، به صورت زیر:


static void Main(string[] args)
{
ArrayList list = new ArrayList();

// string type
list.Add("hello");
list.Add("C#‎");
// integer type
list.Add(12);
list.Add(13);
list.Add(20);
// double type
list.Add(12.5);
list.Add(16.5);

int sum = 0;
int num;

foreach (var item in list)
{
if (int.TryParse(item.ToString(), out num))
{
sum += num;
}
}

Console.WriteLine(sum.ToString());


Console.ReadLine();
}










حالا فکر کنید که توی برنامه نویسی به اشتباه عملیات Casting رو انجام نداده باشید اون موقع چه اتفاقی ممکنه بیافته !!؟؟

درسته باعث ایجاد خطای کامپایلر میشه، کامپایلر وقتی به خط sum += int.Parse(item.ToString()); درون حلقه میرسه، چون نمی تونه اون به نوع عدد صحیح تبدیل کنه با خطای (Input string was not in a correct format.) مواجه میشه.

ولی در مقابل اگر از جنریک ها استفاده میکردید، کار به زمان اجرا نمی رسید چون موقعی که یک لیست به صورت جنریک تعریف میشه حتماً باید نوعی رو که واسش به صورت پارامتریک ارسال کردید استفاده کنید،

مثلاً شما یک List<int> تعریف می کنید و زمانی که بخوایید یک نوع رشته ای رو برای اون ارسال کنید (با استفاده از list.add(“hello”)))با خطای زمان کامپایل مواجه میشید.!!!

این هم مزیت جنریک ها، البته این رو هم باید بگم که خود ماکروسافت وقتی که جنریک ها رو تولید کرد، به کلیه برنامه نویسان توصیه کرد که دیگه از جنریک ها استفاده کنند، به خاطر همین مزایاش بود دیگه!!!!




انشا الله در ادامه به بررسی وراثت ها در جنریک ها و تعریف Constraint ها (محدودیت ها) در جنریک ها می پردازیم....






پیروز و سربلند باشید.

MDSTmdst
سه شنبه 03 اردیبهشت 1392, 15:45 عصر
باتشکر
ادامه نمی دید....