🧬 جنریکهای پیشرفته: Covariance و راز تبدیل <IEnumerable<string به <IEnumerable<objectتا حالا براتون سوال شده چرا این کد در #C درسته:
IEnumerable<object> list = new List<string>();
ولی این کد خطا میده:
List<object> list = new List<string>();
جواب این سوال تو یه مفهوم پیشرفته و خیلی مهم به اسم Covariance نهفتهست.
1️⃣ Covariance چیست؟
به زبان ساده، Covariance میگه شما میتونید یه نوع جنریک با پارامتر فرزند (مثل <string>) رو به همون نوع جنریک با پارامتر پدر (مثل <object>) تبدیل کنید. (چون string یک نوع از object است).
این قابلیت در #C فقط برای اینترفیسها و دلیگیتها فعاله، نه برای کلاسها.
2️⃣ چرا کلاسها Covariant نیستن؟ (تلهی Type Safety) ⚠️
چرا نمیتونیم یه <List<Bear رو به <List<Animal تبدیل کنیم؟ چون اگه این کار مجاز بود، میتونستیم یه فاجعه منطقی به بار بیاریم و ایمنی نوع (Type Safety) رو که #C بهش افتخار میکنه، از بین ببریم:
class Animal { }
class Bear : Animal { }
class Camel : Animal { }
// لیستی از خرسها
List bears = new List();
// ❌ خطای زمان کامپایل! اگر این خط مجاز بود...
// List animals = bears;
// ...اونوقت میتونستیم یه شتر رو تو لیست خرسها بریزیم!
// animals.Add(new Camel()); // 💥 فاجعه در زمان اجرا!برای جلوگیری از این خطای منطقی، کلاسهای جنریک مثل <
List<T که متدهای Add دارن (یعنی "نوشتنی" هستن)، به صورت پیشفرض Covariant نیستن. اما اینترفیسی مثل <IEnumerable<T که فقط "خواندنی" هست، میتونه Covariant باشه.3️⃣ پس چطور با این محدودیت کار کنیم؟
حالا فرض کنید یه متد Wash داریم که میخواد یه لیستی از حیوانات رو بشوره. اگه ورودی رو <List<Animal بذاریم، نمیتونیم بهش <List<Bear پاس بدیم.
راه حل، جنریک کردن خود متد با استفاده از قیدهاست:
public class ZooCleaner
{
// این متد، هر نوع لیستی رو قبول میکنه که T اون از Animal ارث برده باشه
public static void Wash<T>(List<T> animals) where T : Animal
{
foreach (T animal in animals)
{
Console.WriteLine($"Washing a {animal.GetType().Name}");
}
}
}
// --- نحوه استفاده ---
List bears = new List();
ZooCleaner.Wash(bears); // ✅ حالا درسته!
🤔 حرف حساب و تجربه شما
Covariance
یه مفهوم عمیقه که اساس کارکرد خیلی از اینترفیسهای مهم داتنت مثل <IEnumerable<T هست. درک اون، شما رو به درک عمیقتری از سیستم تایپینگ #C میرسونه.
🔖 هشتگها:
#CSharp #DotNet #OOP #Generics #AdvancedCSharp