📖 سری آموزشی کتاب C# 12 in a Nutshell
در دنیای شیءگرایی، دو تا از قدرتمندترین مفاهیم، Overloading (چند متد با اسم یکسان) و Polymorphism (چندریختی) هستن. اما وقتی این دو با هم روبرو میشن، چه اتفاقی میفته؟ کامپایلر چطور تصمیم میگیره کدوم متد رو اجرا کنه؟
جواب این سوال، یکی از ظریفترین و مهمترین نکات #C هست که درک عمیق شما از زبان رو نشون میده.
فرض کنید این کلاسها و دو متد Foo رو داریم که override نشدن، بلکه overload شدن:
قانون اینه: انتخاب بین متدهای Overload شده، در زمان کامپایل و بر اساس نوع متغیر شما اتفاق میفته، نه نوع واقعی آبجکتی که در زمان اجرا داخل اون متغیره.
این رفتار با override کردن کاملاً متفاوته!
حالا اگه بخوایم این تصمیم رو به زمان اجرا موکول کنیم تا بر اساس نوع واقعی آبجکت تصمیم گرفته بشه، میتونیم متغیر رو به dynamic کست کنیم. این کار به DLR (Dynamic Language Runtime) میگه که در زمان اجرا، بهترین متد رو پیدا کنه.
🤔 حرف حساب و تجربه شما
این تفاوت ظریف، نشون میده که Overloading یک نوع چندریختی در زمان کامپایل (Static Polymorphism) هست، در حالی که override کردن، چندریختی در زمان اجرا (Dynamic Polymorphism) رو پیاده میکنه.
⚔️ دوئل Overloading و Polymorphism: کدام متد اجرا میشود؟
در دنیای شیءگرایی، دو تا از قدرتمندترین مفاهیم، Overloading (چند متد با اسم یکسان) و Polymorphism (چندریختی) هستن. اما وقتی این دو با هم روبرو میشن، چه اتفاقی میفته؟ کامپایلر چطور تصمیم میگیره کدوم متد رو اجرا کنه؟
جواب این سوال، یکی از ظریفترین و مهمترین نکات #C هست که درک عمیق شما از زبان رو نشون میده.
1️⃣ صحنه نبرد: دو متد Overload شده
فرض کنید این کلاسها و دو متد Foo رو داریم که override نشدن، بلکه overload شدن:
public class Asset { }
public class House : Asset { }
static void Foo(Asset a) => Console.WriteLine("Foo(Asset) called");
static void Foo(House h) => Console.WriteLine("Foo(House) called");2️⃣ قانون بازی: انتخاب در زمان کامپایل! ⚖️
قانون اینه: انتخاب بین متدهای Overload شده، در زمان کامپایل و بر اساس نوع متغیر شما اتفاق میفته، نه نوع واقعی آبجکتی که در زمان اجرا داخل اون متغیره.
این رفتار با override کردن کاملاً متفاوته!
House h = new House();
// اینجا نوع متغیر h در زمان کامپایل House است، پس کامپایلر Foo(House) رو انتخاب میکنه.
Foo(h);
// خروجی: Foo(House) called
Asset a = new House();
// مهم! اینجا با اینکه آبجکت داخل a از نوع House است،
// اما نوع متغیر a در زمان کامپایل Asset است!
// پس کامپایلر، Foo(Asset) رو انتخاب میکنه.
Foo(a);
// خروجی: Foo(Asset) called
3️⃣ راه فرار: استفاده از dynamic 🚀
حالا اگه بخوایم این تصمیم رو به زمان اجرا موکول کنیم تا بر اساس نوع واقعی آبجکت تصمیم گرفته بشه، میتونیم متغیر رو به dynamic کست کنیم. این کار به DLR (Dynamic Language Runtime) میگه که در زمان اجرا، بهترین متد رو پیدا کنه.
Asset a = new House();
Foo((dynamic)a);
// خروجی: Foo(House) called
🤔 حرف حساب و تجربه شما
این تفاوت ظریف، نشون میده که Overloading یک نوع چندریختی در زمان کامپایل (Static Polymorphism) هست، در حالی که override کردن، چندریختی در زمان اجرا (Dynamic Polymorphism) رو پیاده میکنه.
🔖 هشتگها:
#DotNet #OOP #Polymorphism #Overloading