با عرض سلام و وقت بخیر خدمت کاربران سایت پی وی لرن ، با دوره کامل آموزش #C در خدمت شما دوستان هستیم . در بخش قبلی با مبحث generic ها در #C آشنا شدید. در این بخش قصد داریم شما را با محدودیت های generic در #C و انواع محدودیت های عمومی در سی شارپ آنها آشنا کنیم.
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; } } |
گاهی وقت ها، نیاز داریم که زمان ساخت شئ، T در GenericType، تنها نوع داده ای که از نوع Value Type و یا فقط Reference Typeباشد را قبول کند. برای اینکار، می توانیم از Constraint ها استفاده کنیم.
برای استفاده از Constraint ها از کلمه کلیدی where استفاده می کنیم.
در مثال زیر، MyGenericClass محدودیت هایی را مشخص می کند که تنها با یک نوع ارجاعی می توانند با MyGenericClass استفاده شوند. این بدین معنی است نوع های Struct و کلا مقدار محور نمیتوانند از آن استفاده کنند و اگر چنین شود کامپایلر خطایی را برمیگرداند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class MyGenericClass<T> where T: class { 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; } } |
بنابراین اکنون نمیتوانید int را به عنوان نوع نگهدارنده استفاده کنید. در زیر یک خطای زمان کامپایل ارائه می شود.
1 | MyGenericClass<int> intGenericClass = new MyGenericClass<int>(10); |
انواع رشته یا هر نوع کلاس معتبر هستند زیرا از انواع ارجاعی (reference type) هستند.
1 2 3 | MyGenericClass<string> strGenericClass = new MyGenericClass<string>("Hello World"); MyGenericClass<Student> strGenericClass = new MyGenericClass<Student>(new Student()); |
توضیحات | Constraint |
---|---|
فقط انواع ارجاعی (reference type) را قبول می کند | where T : class |
فقط انواع مقداری (value type) را قبول می کند | where T: struct |
تنها کلاس هایی را میتوان استفاده کرد که سازنده پیش فرض داشته باشند | where T: new() |
نوع آن باید از کلاس پایه مشخص باشد و یا از آن کلاس مشخص حاصل شده باشد | where T: <base class name> |
باید از اینترفیس مشخص شده حاصل شده باشد | where T: <interface name> |
نوع عرضه شده برای T باید از آرگمان ارائه شده برای U باشد یا از آن حاصل شود. | where T: U |
یک کلاس عمومی می تواند محدودیت های چندگانه را داشته باشد که در زیر نشان داده شده است.
1 2 3 4 | class MyGenericClass<T, U> where T: class where U:struct { ... } |
به کد زیر دقت کنید :
1 2 3 4 5 6 7 8 9 10 | class MyGenericClass<T> where T: class { public T genericMethod<U>(T genericParameter, U anotherGenericType) where U: struct { Console.WriteLine("Generic Parameter of type {0}, value {1}", typeof(T).ToString(),genericParameter); Console.WriteLine("Return value of type {0}, value {1}", typeof(T).ToString(), genericMemberVariable); return genericMemberVariable; } } |
در این قسمت با نحوه اعمال محدودیت (constraints) روی generic ها آشنا شدید.
در جلسه بعد قصد داریم در رابطه با مجموعه های عمومی (Generic Collection) در #C صحبت کنیم.