👑 پدر همه تایپها: object و راز Boxing/Unboxing در #C
تا حالا شده بخواید یه کالکشن بسازید که بتونه هر نوع دادهای رو تو خودش نگه داره، از int و bool گرفته تا string و کلاسهای خودتون؟
این کار به لطف پدر همه تایپها در داتنت، یعنی System.Object، ممکنه. اما این قابلیت، یه راز عملکردی مهم به اسم Boxing و Unboxing رو تو دل خودش داره.
1️⃣ object: جد بزرگ همه!
در #C، هر نوع دادهای، چه Value Type (مثل int) و چه Reference Type (مثل string)، به صورت پنهان از کلاس System.Object ارثبری میکنه. این یعنی شما میتونید هر متغیری رو به یه متغیر از نوع object تبدیل کنید (Upcast).
مثال (یک Stack همهکاره):
public class Stack
{
int position;
object[] data = new object[10];
public void Push(object obj) => data[position++] = obj;
public object Pop() => data[--position];
}
// --- نحوه استفاده ---
var stack = new Stack();
stack.Push("hello");
stack.Push(123); // حتی int!
stack.Push(false); // حتی bool!
// موقع خروج، باید Downcast کنیم
int myNumber = (int)stack.Pop(); // 123
string myString = (string)stack.Pop(); // "hello"
2️⃣ جادوی پشت پرده: Boxing و Unboxing 🎁
سوال اینجاست: چطور یه int که Value Type هست، میتونه مثل یه object که Reference Type هست رفتار کنه؟ با جادوی Boxing و Unboxing.
• Boxing (بستهبندی):
وقتی شما یه Value Type (مثل int) رو داخل یه متغیر object میریزید، CLR یه "جعبه" روی هیپ (Heap) میسازه، کپی از مقدار شما رو داخل اون میذاره و رفرنس اون جعبه رو به شما میده.
• Unboxing (باز کردن بسته):
وقتی میخواید مقدار رو از اون جعبه در بیارید، عملیات برعکس یعنی Unboxing اتفاق میفته که نیاز به کست صریح داره.
int x = 9;
object obj = x; // Boxing: مقدار x در یک جعبه روی هیپ کپی میشود
int y = (int)obj; // Unboxing: مقدار از جعبه کپی شده و به y ریخته میشود
3️⃣ تلهها و نکات مهم ⚠️ تله InvalidCastException:
Unboxing
باید به نوع دقیق و اصلی انجام بشه. اگه سعی کنید یه int باکس شده رو به long آنباکس کنید، با خطای InvalidCastException مواجه میشید.
object obj = 9; // این یک int باکس شده است
// long l = (long)obj; // ❌ InvalidCastException!
تله کپی شدن مقدار:
نکته حیاتی: Boxing یه کپی از مقدار شما رو میسازه. این یعنی اگه بعداً متغیر اصلی رو تغییر بدید، مقدار داخل جعبه دستنخورده باقی میمونه!
int i = 3;
object boxed = i; // یک کپی از 3 در boxed قرار گرفت
i = 5; // تغییر i اصلی، تأثیری روی مقدار باکس شده ندارد
Console.WriteLine(boxed); // خروجی: 3
🤔 حرف حساب و تجربه شما
دونستن مفهوم Boxing و Unboxing برای درک پرفورمنس در #C حیاتیه، چون این عملیاتها هزینه حافظه و پردازش دارن. به همین دلیله که جنریکها (Generics) اختراع شدن تا جلوی این اتفاق رو بگیرن (که بعداً بهش میرسیم).
🔖 هشتگها:
#OOP #MemoryManagement #Boxing