کلاس Generic در #C
یکشنبه 8 فروردین 1395در این مقاله شما با کلاس Generic و نحوه ی تعریف آن آشنا میشوید و علت بکار گیری آنها در کد مطلع خواهید شد. ما سعی کرده ایم که این مطلب را با مثال و نمونه کد توضیح دهیم تا درک آن راحت و آسان باشد.
در بیشتر موارد ،ما با تعریف یک سری کلاس ها، اقدام به کپسوله سازی رفتارهای یک شی در کد می کنیم و به این ترتیب اشیاء قدرتمندی از این کلاسها می سازیم سپس میتوانیم از آنها نمونه ایجاد کنیم. این کلاسها به دو روش ایجاد میشوند : هم توسط برنامه نویس و هم توسط زبانی که در آن برنامه نویسی میکنید. ما میتوانیم یک کلاس را با اصلاح رفتارهایش قدرتمندتر سازیم و آن را به گونه ای برنامه نویسی کنیم که نه تنها از انواع داده ای که برای آنها کد نوشتیم پیشتیبانی کند بلکه از سایر انواع داده ها نیز پیشتیبانی کند. Generic این اجازه را به ما میدهد. ما میتوانیم به وسیله ی آن کد خود را اصلاح کنیم و یک لایه اضافی از انتزاع را به آن اضافه میکنیم مطمئنا برای این کار لایه های اطلاعاتی ما نباید hard coded باشند.
توضیح و مثال :
مثال زیر را در نظر بگیرید:
1. public class CustomIntegerStack 2. { 3. int pointer = 0; 4. int[] array; 5. public void Push(int p) { } 6. public int Pop() { } 7. }
کلاسی که در مثال بالا آمده است یک ساختار پایه برای integer stackمیباشد که به ما اجازه میدهد تا نوع داده integer را push و pop کنیم.
فرایند بالا به خوبی عمل میکند اما نواقص زیر را نیز دارد:
1. ما مجبورهستیم که همه ی بخشهای کلاس را بررسی کنیم تا تعیین کنیم که کدام بخش از کلاس نیاز به تغییر دارد.
2. نیاز داریم که یک فرایند تکراری را برای هر نوع جدید تکرار کنیم.
در اینجا یک کلاسgeneric از CustomIntegerStack ایجاد میکنیم. برای این کار باید مراحل زیر را انجام دهید.
1.به جای استفاده از یک نوع مشخص ( که در اینجا integer است ) از حرف T که داده ای از نوع placeholder است استفاده میکنیم.
2. حرف T را بعد از نام کلاس قرار میدهیم.
در نتیجه کلاس مورد نظر به شکل زیر خواهد شد:
1. public class CustomStack<T> 2. { 3. int pointer = 0; 4. T[] array; 5. public void Push(T p) { } 6. public T Pop() { } 7. }
Generic Class :
کلاس Generic یک کلاس واقعی نیست. آنها مانند یک قالب برای کلاسها هستند. در اینجا دو قدم مهم وجود دارد که عبارتنداز :
1.ما ابتدا باید یک کلاس واقعی برای آنها بسازیم.
2.ما میتوانیم از این کلاسهای ساخته شده، نمونه بسازیم.
ایجاد نمونه از یک داده با نوع generic نیاز دارد که : یک کلاس از نوع generic تعریف کنیم، یک constructed type ایجاد کنیم و یک نمونه از constructed type بسازیم.
ایجاد یک کلاس از نوع Generic :
تعریف یک کلاس از نوع Generic ساده با کمی تفاوت مشابه تعریف کلاسهای معمولی است .
1. ما باید علامت < > بعد از نام کلاس قرار دهیم .
2. داخل علامت < > یک placeholders قرار میدهیم که نوع داده ی ورودی را مشخص میکند.
ما نوع پارامترها را در بدنه ی کلاس Generic مورد استفاده قرار میدهیم.
class ClassName<T1, T2>{ }
ایجاد یک constructed type
بعد از ایجاد نوع generic باید به کامپایلر در مورد نوع واقعی آن اطلاع رسانی کنیم. کامپایلر انواع واقعی را میگیرند و یک constructed type ایجاد میکند. syntax برای ایجاد constructed type به صورت زیر است:
ClassName < string, int>
ایجاد متغیر و نمونه ها :
به روش زیر از کلاس مثال بالا نمونه میسازیم :
ClassName < string, int > c1 = new ClassName < string, int > ();
var c1 = new ClassName < string, int > ();
استفاده از Generic در CustomStack
1. public class CustomStack<T> 2. { 3. public T[] array; 4. public int pointer = 0; 5. private const int maxStack = 10; 6. public bool isStackFull { get { return pointer >= maxStack; } } 7. public bool isStackEmpty { get { return pointer <= 0; } } 8. 9. public void Push(T x) 10. { 11. if (!isStackFull) 12. { 13. array[pointer++] = x; 14. } 15. } 16. 17. public T Pop() 18. { 19. return !isStackEmpty ? array[--pointer] : array[0]; 20. } 21. 22. public CustomStack() 23. { 24. array = new T[maxStack]; 25. } 26. 27. public void Display() 28. { 29. for (int i = pointer-1; i >= 0; i--) 30. { 31. Console.WriteLine("Current Value: {0}", array[i]); 32. } 33. } 34. } 35. static void Main(string[] args) 36. { 37. var intStack = new CustomStack<int>(); 38. var strStack = new CustomStack<string>(); 39. intStack.Push(1); 40. intStack.Push(2); 41. intStack.Push(3); 42. intStack.Push(4); 43. intStack.Display(); 44. 45. strStack.Push("Hello world"); 46. strStack.Push("Custom stack"); 47. strStack.Display(); 48. 49. intStack.Pop(); 50. intStack.Display(); 51. 52. strStack.Pop(); 53. strStack.Display(); 54. Console.ReadKey(); 55. }
خروجی :
Current Value: 4
Current Value: 3
Current Value: 2
Current Value: 1
Current Value: Hello world
Current Value: Custom stack
Current Value: 3
Current Value: 2
Current Value: 1
Current Value: Hello world
Where Clauses :
در generic شرط ها و محدودیت ها در where clauses لیست میشوند. مانند syntax زیر :
class WhereClauseClass<T1, T2> where T2 : Customer{}
متد Generic :
متد Generic میتواند هم در کلاسهای Generic و هم در کلاسهای non generic تعریف شود و همچنین میتواند از نوع struct و interface نیز باشد. متدهای Generic لیستی از پارامترها را میگیرند و همچنین میتوانید برای آنها شرط بگذارید، البته گذاشتن شرط اختیاری است و میتوان قسمت شرط را حذف کرد. تعریف متد Generic به صورت قطعه کد زیر میباشد.
public void DisplayData<S, T>(S s, T t) where S : Person { }
فراخوانی یک متد Generic
برای فراخوانی یک متد Generic ، لازم است که تابعی که متد Generic را فراخوانی میکند با آن ارتباط برقرار کند. به کد زیر دقت کنید.
1. public void DisplayData<T1, T2>(T1 t1, T2 t2) 2. { 3. T1 obj1 = t1; 4. T2 boj2 = t2; 5. } 6. DisplayData<string, int>(strVal, intVal);
یک مثال از متد generic به همراه خروجی :
در قطعه کد زیر ، یک متد generic با نام ReverseAndPrint() در یک کلاس non generic با نام GenericExample تعریف شده است .
1. public class GenericExample 2. { 3. static public void ReverseAndPrint<T>(T[] arr) 4. { 5. Array.Reverse(arr); 6. foreach(T item in arr) 7. { 8. Console.WriteLine("{0}", item.ToString()); 9. } 10. } 11. } 12. 13. static void Main(string[] args) 14. { 15. var intArr = new int[] { 3, 5, 7 }; 16. var strArr = new string[] { "first", "second", "third" }; 17. GenericExample.ReverseAndPrint<int>(intArr); 18. GenericExample.ReverseAndPrint<string>(strArr); 19. } 20. public class GenericExample 21. { 22. static public void ReverseAndPrint<T>(T[] arr) 23. { 24. Array.Reverse(arr); 25. foreach(T item in arr) 26. { 27. Console.WriteLine("{0}", item.ToString()); 28. } 29. } 30. } 31. 32. static void Main(string[] args) 33. { 34. var intArr = new int[] { 3, 5, 7 }; 35. var strArr = new string[] { "first", "second", "third" }; 36. GenericExample.ReverseAndPrint<int>(intArr); 37. GenericExample.ReverseAndPrint<string>(strArr); 38. }
خروجی :
7
5
3
first
second
third
- C#.net
- 3k بازدید
- 5 تشکر