با عرض سلام و وقت بخیر خدمت کاربران سایت پی وی لرن ، با دوره کامل آموزش #C در خدمت شما دوستان هستیم . در بخش قبلی با رویداد ها در زبان #C آشنا شدید. در این بخش قصد داریم شما را با generic ها در #C و مزایای Generics در سی شارپ آشنا کنیم.
Generic ها در C# 2.0 به این زبان اضافه شد و به شما اجازه می دهد یک کلاس با متغیرهایی با انواع فیلدها، متد ها، پارامترها و … تعریف کنید. Generics جایگزین این متغیرهای با نوع خاص، در زمان کامپایل می شود.
یک کلاس عمومی را می توان با استفاده از علامتهای بازوبسته <> تعریف کرد. به عنوان مثال، در زیر یک کلاس عمومی (generic) با یک متغیر نوع عمومی (Generic)، تعریف شده است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class MyGenericClass<T> { private T genericMemberVariable; public MyGenericClass(T value) { genericMemberVariable = value; } public T genericMethod(T genericParameter) { Console.WriteLine("Parameter type: {0}, value: {1}", typeof(T).ToString(),genericParameter); Console.WriteLine("Return type: {0}, value: {1}", typeof(T).ToString(), genericMemberVariable); return genericMemberVariable; } public T genericProperty { get; set; } } |
همانطور که در کد بالا دیده می شود، MyGenericClass بهمراه علامت <T> تعریف شده است. علامت <> نشان می دهد که MyGenericClass عمومی است و نوع آن را بعدا تعریف می کند،و در حال حاضر آن را T می نامیم. شما می توانید هر کاراکتر یا کلمه را به جای T وارد کنید.
حالا ، کامپایلر نوع مشخص شده را در هنگام ایجاد یک کلاس به آن اختصاص می دهد. به عنوان مثال، کد زیر از نوع داده int استفاده می کند:
1 2 3 | MyGenericClass<int> intGenericClass = new MyGenericClass<int>(10); int val = intGenericClass.genericMethod(200); |
خروجی :
1 2 | Parameter type: int, value: 200 Return type: int, value: 10 |
شکل زیر نشان می دهد که چگونه کامپایلر T را با int در MyGenericClass جایگزین می کند.
در کدهای بالا کلاس MyGenericClass به صورت زیر کامپایل می شود.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class MyGenericClass { private int genericMemberVariable; public MyGenericClass(int value) { genericMemberVariable = value; } public int genericMethod(int genericParameter) { Console.WriteLine("Parameter type: {0}, value: {1}", typeof(int).ToString(), genericParameter); Console.WriteLine("Return type: {0}, value: {1}", typeof(int).ToString(), genericMemberVariable); return genericMemberVariable; } public int genericProperty { get; set; } } |
شما می توانید از هر نوع داده ای در هنگام ایجاد MyGenericClass استفاده کنید. به عنوان مثال، مثال زیر از نوع رشته استفاده می کند.
1 2 3 4 | MyGenericClass<string> strGenericClass = new MyGenericClass<string>("Hello Generic World"); strGenericClass.genericProperty = "This is a generic property example."; string result = strGenericClass.genericMethod("Generic Parameter"); |
خروجی :
1 2 | Parameter type: string, value: Generic Parameter Return type: string, value: Hello Generic World |
وقتی که از یک کلاس پایه عمومی استفاده می کنید، شما باید یک نوع آرگومان بجای پارامتر نوع عمومی کلاس پایه همانطور که در زیر نشان داده شده است ارائه دهید.
1 2 3 4 | class MyDerivedClass : MyGenericClass<string> { //implementation } |
اگر شما می خواهید از کلاس عمومی ارث بری کنید ، نیازی به مشخص کردن نوع برای کلاس پایه عمومی نیست. همانند مثال زیر :
1 2 3 4 | class MyDerivedClass<U> : MyGenericClass<U> { //implementation } |
اگر کلاس پایه عمومی دارای محدودیت باشد، کلاس مشتق شده باید از همان محدودیت ها استفاده کند.
1 2 3 4 5 6 7 8 9 | class MyGenericClass<T> where T: class { // Implementation } class MyDerivedClass<U> : MyGenericClass<U> where U: class { //implementation } |
همانطور که در بخش قبلی آموخته اید، ساختار delegate باید دقیقا شبیه متدی باشد که آن را فراخوانی می کند. delegate عمومی نیز می تواند به همان شکل با نوع عمومی تعریف شود.
برای مثال، delegate عمومی زیر را در نظر بگیرید که دو پارامتر عمومی را می گیرد:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class Program { public delegate T add<T>(T param1, T param2); static void Main(string[] args) { add<int> sum = AddNumber; Console.WriteLine(sum(10, 20)); add<string> conct = Concate; Console.WriteLine(conct("Hello","World!!")); } public static int AddNumber(int val1, int val2) { return val1 + val2; } public static string Concate(string str1, string str2) { return str1 + str2; } } |
خروجی :
1 2 | 30 Hello World!! |
در مثال بالا، متد add یک delegate عمومی است که در متد Main به صورت دو نوع int و String فراخوانی شده است.
در ابتدا این delegate به متد AddNumber اشاره می کند که دارای پارامترهای نوع int است. و در ادامه کدها به متد Concate اشاره می کند که دارای پارامتر های نوع رشته هستند ، به این ترتیب، شما می توانید در delegate های عمومی از انواع مختلف پارامترها استفاده کنید.
نکته : یک delegate عمومی می تواند به متدهایی با انواع پارامترهای مختلف اشاره کند. ولی، تعداد پارامترها باید یکسان باشند.
میتوان از Generic ها در موارد زیر استفاده کرد :
در این بخش با generic ها در زبان #C آشنا شدید.
در قسمت بعدی قصد داریم در رابطه با محدودیت ها (Constraints) در generic صحبت کنیم.
رها
خیلی مفید و مختصر و عالی بود . ممنون از لطف شما.
hadi
سلام. بسیار بسیار ممنونم که اینقدر شیوا و روان توضیح دادید. ممنونم از زحمات شما. هادی
امیر سلیمی
آقا عالی