
آموزش جنریک ها Generics در سی شارپ و دات نت
آموزش جنریک ها Generics در سی شارپ و دات نت یکی دیگر از آموزش های گروه آموزشی پرووید می باشد که در این قسمت آن را به شما معرفی می کنیم. این بسته ی آموزشی نیز یکی از دوره های آموزشی دیگر که در حوزه ی فارسی سازی آموزش های انگلیسی تنظیم شده است می باشد. عنوان این بسته ی آموزشی جنریک ها در سی شارپ است که با نام اصلی C# Generics از شرکت Pluralsight منتشر شده است.
جنریک در دات نت و سی شارپ
علاوه بر کلاس های کالکشنی جنریک که در فریم ورک دات نت وجود دارند، شما می توانید از کلاس های خاص خود که به صورت جنریک تعریف میشوند نیز استفاده کرده و از این طریق، مباحثی از قبیل type safety و efficiency را با آنها به دست بیاورید.

استفاده کردن از جنریک ها به طور کلی دارای مزیت های بسیاری را به کد شما اضافه می کنند که برخی از آنها را در قسمت زیر، بررسی میکنیم.
- استفاده کردن از جنریک ها و کلاس ها و متدهای جنریک، باعث می شوند که قابلیت هایی از قبیل reusability و یا همان قابلیت استفاده مجدد، type safety و یا امنیت type ها و نهایتاً performance و یا کارایی برنامه افزایش پیدا کند.
- از جنریک ها، بیشتر در تعریف کلاس های کالکشنی استفاده میکنیم. چرا که این کلاس ها نیازمند آن هستند که بتوانند با انواع داده مختلفی کار کند. کتابخانه کلاس های فریم ورک دات نت شامل کلاس های کالکشنی جنریکی می باشد که در یک namespace با نام System.Collections.Generic تعریف شدهاند. این موضوع باعث میشود که استفاده کردن از کلاس هایی از قبیل ArrayList که در یک namespace به نام System.Collections وجود دارند توصیه نشود.
- علاوه بر کلاسهای کالکشنی از قبل موجود در فریم ورک دات نت، امکان تعریف کردن event ها و متدها و کلاسها و delegate ها و interface های جنریک نیز وجود دارد.
- کلاس های جنریک می توانند type parameter خود را به صورت مقیدی تعریف کرده تا مصرفکننده کلاس و یا متد جنریک مجبور باشد برای استفاده کردن از آنها حتما شرایط مورد نظر را رعایت کند. برای مثال، می توان طوری کد نویسی کرد که type parameter جنریک یک کلاس و یا متد حتماً یک reference type و یا value type باشد. اطلاعات مربوط به type هایی که به عنوان generic type argument مربوط به کلاسها و یا متدهای جنریک تعریف میشوند در زمان run time مشخص گردیده و میتوان آنها را با استفاده از reflection به دست آورد.
کاربردهای Generics در طراحی کلاس ها و متدهای سی شارپ
یکی از کاربردهای مهم Generics در C#، امکان طراحی کلاس ها و متدهایی است که بتوانند با انواع داده مختلف کار کنند، بدون اینکه برای هر نوع داده به پیاده سازی جداگانه نیاز داشته باشید. برای مثال، می توانید یک کلاس برای نگهداری اطلاعات تعریف کنید که هم با مقادیر عددی و هم با رشته های متنی کار کند. این قابلیت باعث کاهش کدهای تکراری و افزایش قابلیت استفاده مجدد از کد می شود و به شما کمک می کند ساختارهای انعطاف پذیرتری در برنامه های دات نت طراحی کنید.
استفاده از Generics تنها به کلاس ها محدود نمی شود و متدها، اینترفیس ها و Delegate ها نیز می توانند به صورت جنریک تعریف شوند. با این روش، نوع داده مورد استفاده هنگام فراخوانی متد یا استفاده از کلاس مشخص می شود و کامپایلر می تواند بسیاری از خطاهای مربوط به ناسازگاری انواع داده را شناسایی کند. آشنایی با این کاربردها برای توسعه دهندگانی که می خواهند کدهای قابل نگهداری تر و توسعه پذیرتری در پروژه های C# بنویسند، اهمیت زیادی دارد.
تفاوت کلاس های کالکشنی جنریک و غیرجنریک در C#
در برنامه نویسی با دات نت، کالکشن ها برای نگهداری و مدیریت مجموعه ای از داده ها استفاده می شوند. کالکشن های جنریک مانند `List<T>` و `Dictionary<TKey, TValue>` به شما اجازه می دهند نوع داده عناصر یا کلیدها و مقادیر را مشخص کنید. برای مثال، با تعریف یک `List<int>` می توانید مجموعه ای از اعداد صحیح داشته باشید و از اضافه شدن مقادیر ناسازگار با نوع مورد انتظار جلوگیری کنید. این روش در مقایسه با استفاده از کالکشن های غیرجنریک، امنیت نوع داده بیشتری فراهم می کند.
یکی دیگر از مزایای کالکشن های جنریک، کاهش نیاز به تبدیل نوع داده هنگام خواندن مقادیر است. در کالکشن های غیرجنریک که معمولاً با `object` کار می کنند، ممکن است برای استفاده از مقدار ذخیره شده به تبدیل نوع نیاز داشته باشید. این موضوع به ویژه هنگام کار با انواع مقداری می تواند باعث عملیات Boxing و Unboxing شود. شناخت تفاوت این دو روش به شما کمک می کند هنگام انتخاب ساختار مناسب برای نگهداری داده ها در برنامه های .NET، تصمیم دقیق تری بگیرید.
آشنایی با Constraints و Covariance در Generics
در برخی شرایط، یک کلاس یا متد جنریک نباید با هر نوع داده ای کار کند. در C# می توانید با استفاده از `Constraints` محدودیت هایی برای پارامتر نوع تعریف کنید؛ برای مثال، مشخص کنید که نوع مورد استفاده باید یک اینترفیس مشخص را پیاده سازی کرده باشد یا از یک کلاس پایه ارث بری کند. این محدودیت ها به کامپایلر اطلاعات بیشتری درباره قابلیت های نوع مورد انتظار می دهند و امکان استفاده از اعضای مشخصی از آن نوع را در پیاده سازی کلاس یا متد فراهم می کنند.
مفاهیم `Covariance` و `Contravariance` نیز به نحوه سازگاری انواع جنریک با یکدیگر مربوط می شوند. این قابلیت ها به ویژه هنگام کار با اینترفیس ها و Delegate های جنریک اهمیت پیدا می کنند و به شما اجازه می دهند در شرایط مشخص، از روابط وراثت میان انواع داده استفاده کنید. درک این مفاهیم برای توسعه دهندگانی مفید است که با API های دات نت، اینترفیس های جنریک و ساختارهای پیشرفته C# سروکار دارند و می خواهند رفتار سیستم نوع دهی زبان را بهتر بشناسند.
بررسی رابطه Generics و Reflection در دات نت
`Reflection` در دات نت قابلیتی است که امکان بررسی اطلاعات مربوط به انواع داده، کلاس ها، متدها و اعضای یک برنامه را در زمان اجرا فراهم می کند. ترکیب Reflection با Generics به شما اجازه می دهد اطلاعات مربوط به انواع جنریک و پارامترهای نوع آن ها را بررسی کنید. برای مثال، می توانید مشخص کنید که یک نوع داده جنریک است یا اطلاعات مربوط به آرگومان های نوع آن را به دست آورید. این قابلیت در سناریوهایی که ساختار برنامه باید به صورت پویا بررسی شود، کاربرد دارد.
یادگیری ارتباط میان Generics و Reflection به شما کمک می کند رفتار انواع جنریک را فراتر از زمان کامپایل درک کنید. در این زمینه، شناخت اطلاعات متادیتا، بررسی نوع های ساخته شده از کلاس های جنریک و آشنایی با نحوه شناسایی پارامترهای نوع اهمیت دارد. این مباحث برای توسعه دهندگانی مناسب هستند که با ابزارهای پیشرفته دات نت کار می کنند و می خواهند درک عمیق تری از سیستم نوع دهی C# و امکانات بررسی ساختار برنامه در زمان اجرا به دست آورند.
سرفصل مطالب آموزش ویدئویی جنریک ها (Generics) در دات نت و سی شارپ
فصل اول: کاربرد جنریک ها در زبان برنامه نویسی سی شارپ
- مقدمه
- بررسی مسأله پیش رو و پیاده سازی یک بافر
- حل کردن مشکل با استفاده از آبجکت ها
- استفاده کردن از روش Copy و Paste کردن
- بررسی Generic Type Parameters ها
- بررسی یک کلاس بافر چرخشی جنریک
- بررسی واژه گان مربوط به کار کردن با جنریک ها
- جمع بندی
فصل دوم: کارکردن با کلاس های کالکشنی جنریک
- مقدمه
- بررسی کلاس لیست
- بررسی کلاس Queue
- بررسی کلاس Stack
- بررسی کلاس Set
- بررسی کلاس Linked List
- استفاده کردن از نگاشت ها
- مرتب کردن
- جمع بندی
فصل سوم: بررسی کلاس ها و اینترفیس های جنریک
- مقدمه
- بررسی نیازمندی های جدید
- تعریف یک اینترفیس برای کلاس بافر
- تعریف کردن یک کلاس بافر دیگر
- پیاده سازی روند چرخشی بافر
- بررسی اینترفیس جنریک IEnumerable
- بررسی اینترفیس های کالکشنی
- مقایسه کردن عناصر درون یک کالکشن
- تمیز کردن کلاس های جنریک
- جمع بندی
فصل چهارم: بررسی متدها و دلیگیت های جنریک
- مقدمه
- بررسی متدهای جنریک
- بررسی Extension Method ها
- بررسی دلیگیت های جنریک
- بررسی دلیگیت ها
- تبدیل کردن با استفاده از کلاس Converter
- بررسی Event ها و جنریک ها
- جمع بندی
فصل پنجم: بررسی Constraints ، Covariance, و Contravariance
- مقدمه
- مباحث مربوط به جنریک ها
- بررسی Model Object ها
- هدف از این فصل
- بررسی Repository ها و Constraint ها
- بررسی Commit و Query
- ایجاد کردن یک Interface Constraint
- بررسی دیگر Constraint ها
- بررسی Covariance ها
- جمع بندی
فصل ششم: کاربرد جنریک ها و Reflection
- مقدمه
- نمونه سازی از یک کلاس جنریک
- اجرا کردن یک متد جنریک
- ساختن یک IOC Container
- بررسی رزولوشن مربوط به کلاس های ساده
- کار کردن با توابع سازنده
- کار کردن با Unbound Generic ها
- جمع بندی
فصل هفتم: نکات نهایی مربوط به جنریک ها
- مقدمه
- بررسی جنریک ها و Enum ها
- بررسی یک مشکل ساده برای پیاده سازی یک تابع ریاضی
- استفاده کردن از Base Type ها
- استفاده از جنریک ها و متدهای Static
- جمع بندی







