جنریکها در C#
جنریکها در C# یکی از ویژگیهای قدرتمند زبان سیشارپ هستند که امکان نوشتن کدهایی انعطافپذیر، امن از نظر نوع داده و قابل استفاده مجدد را فراهم میکنند. با استفاده از جنریکها، میتوانیم کلاسها، متدها و ساختارهای دادهای طراحی کنیم که با انواع دادههای مختلف کار کنند بدون آنکه نیاز به تبدیل نوع داده (type casting) یا کپی کردن کد داشته باشیم. این ویژگی به خصوص در پیادهسازی کولهکشنها مانند List
در توسعه سیشارپ، از جنریکها زمانی استفاده میکنیم که یک منطق واحد برای انواع مختلف دادهها قابل اعمال باشد. این کار باعث افزایش قابلیت نگهداری، خوانایی و امنیت کد میشود و خطاهای زمان اجرا کاهش مییابد. همچنین جنریکها با اصول برنامهنویسی شیءگرا مانند encapsulation و abstraction سازگار هستند و در طراحی معماری نرمافزار به بهبود ماژولاریتی و performance کمک میکنند.
در این آموزش، شما یاد خواهید گرفت چگونه کلاسها و متدهای جنریک را تعریف کنید، محدودیتهای نوع داده (constraints) اعمال کنید و جنریکها را در پروژههای واقعی سیشارپ استفاده نمایید. همچنین مفاهیمی مانند بهینهسازی عملکرد، جلوگیری از خطاهای حافظه و طراحی الگوهای معماری با جنریکها پوشش داده خواهد شد.
مثال پایه
textusing System;
namespace GenericsDemo
{
// تعریف یک کلاس جنریک ساده
public class Box<T>
{
private T content;
public void Add(T item)
{
content = item;
}
public T Get()
{
return content;
}
}
class Program
{
static void Main(string[] args)
{
// نمونهسازی کلاس جنریک با int
Box<int> intBox = new Box<int>();
intBox.Add(42);
Console.WriteLine("محتوای Box: " + intBox.Get());
// نمونهسازی کلاس جنریک با string
Box<string> stringBox = new Box<string>();
stringBox.Add("سلام دنیا");
Console.WriteLine("محتوای Box: " + stringBox.Get());
}
}
}
در این مثال، کلاس Box
این پیادهسازی از نظر نوع داده امن است و کامپایلر بررسی میکند که تنها نوع مشخص شده استفاده شود. استفاده از جنریکها باعث کاهش نیاز به type casting، افزایش قابلیت استفاده مجدد و کاهش خطاهای زمان اجرا میشود. این روش با اصول OOP و بهترین شیوههای توسعه سیشارپ همخوانی دارد.
مثال کاربردی
textusing System;
using System.Collections.Generic;
namespace AdvancedGenericsDemo
{
// تعریف یک Repository جنریک با محدودیت نوع داده
public class Repository<T> where T : class
{
private List<T> items = new List<T>();
public void Add(T item)
{
if (item == null)
throw new ArgumentNullException(nameof(item), "آیتم نمیتواند null باشد");
items.Add(item);
}
public T Find(Predicate<T> predicate)
{
return items.Find(predicate);
}
public void DisplayAll()
{
foreach (var item in items)
{
Console.WriteLine(item.ToString());
}
}
}
class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
public override string ToString()
{
return $"{Name} - {Price} تومان";
}
}
class Program
{
static void Main(string[] args)
{
Repository<Product> productRepo = new Repository<Product>();
productRepo.Add(new Product { Name = "Laptop", Price = 70000 });
productRepo.Add(new Product { Name = "Smartphone", Price = 40000 });
Console.WriteLine("تمام محصولات:");
productRepo.DisplayAll();
Product expensiveProduct = productRepo.Find(p => p.Price > 50000);
Console.WriteLine("محصول گران: " + expensiveProduct);
}
}
}
در این مثال، Repositorywhere T : class
است که اجازه میدهد تنها انواع مرجعی استفاده شوند. متد Add با بررسی null و exception handling از خطاهای احتمالی جلوگیری میکند. متد Find برای جستجو بر اساس شرط مشخص و DisplayAll برای نمایش تمامی آیتمها استفاده میشوند.
کلاس Product به عنوان نمونه واقعی استفاده شده است و متد ToString برای نمایش ساده اطلاعات پیادهسازی شده است. این مثال نشان میدهد چگونه جنریکها، اصول OOP، الگوریتمها و مدیریت خطا را ترکیب میکنند و بهترین شیوههای سیشارپ را رعایت میکنند.
بهترین شیوهها و نکات کلیدی برای جنریکها در C#:
- از محدودیتهای نوع داده برای افزایش امنیت استفاده کنید.
- منابع غیرمدیریتشده را در کپسولهای جنریک ذخیره نکنید.
- از کولهکشنهای جنریک داخلی مانند List
و Dictionary\ استفاده کنید. - بررسی null و مدیریت استثناها برای ورودیها اعمال شود.
- جنریکها را بیش از حد عمومی نکنید.
- هنگام دیباگ، به نوع داده واقعی توجه کنید.
- برای بهینهسازی عملکرد، از Boxing/Unboxing غیرضروری اجتناب کنید.
- اعتبارسنجی ورودیها و محافظت از دادههای حساس برای امنیت الزامی است.
📊 جدول مرجع
سیشارپ Element/Concept | Description | Usage Example |
---|---|---|
کلاس جنریک | کلاسی که میتواند با انواع مختلف کار کند | public class Box<T> { T content; } |
متد جنریک | متدی که میتواند انواع مختلف داده را پردازش کند | public T GetItem<T>(T item) { return item; } |
Constraints | اعمال محدودیت روی نوع داده | where T : class, new() |
List<T> | کولهکشن جنریک | List<int> numbers = new List<int>(); |
Dictionary\<TKey,TValue> | کولهکشن کلید-مقدار | Dictionary\<string,int> ages = new Dictionary\<string,int>(); |
Predicate<T> | delegate برای جستجو یا فیلتر | items.Find(p => p.Price > 50000); |
خلاصه و گامهای بعدی:
جنریکها در C# امکان ایجاد کدهای امن، قابل استفاده مجدد و بهینه را فراهم میکنند. با استفاده صحیح از کلاسها و متدهای جنریک، محدودیتها، و الگوهای طراحی، میتوان معماری ماژولار، عملکرد بالا و خطاهای کم در زمان اجرا ایجاد کرد.
برای یادگیریهای بعدی، مطالعه Stack
🧠 دانش خود را بیازمایید
آزمون دانش شما
درک خود از این موضوع را با سوالات کاربردی بسنجید.
📝 دستورالعملها
- هر سوال را با دقت بخوانید
- بهترین پاسخ را برای هر سوال انتخاب کنید
- میتوانید آزمون را هر چند بار که میخواهید تکرار کنید
- پیشرفت شما در بالا نمایش داده میشود