Boxing هو تحويل نوع قيمة (مثل int) إلى نوع مرجع (object) — بتغليفه في كائن على الـ heap. Unboxing هو العملية العكسية (استخراج القيمة مرة أخرى). كلاهما له تكلفة أداء (تخصيص heap، نسخ)، وفهمهما يساعدك على تجنب الحمل الزائد غير الضروري.
Boxing هو تحويل نوع قيمة (مثل int) إلى نوع مرجع (object) — بتغليفه في كائن على الـ heap. Unboxing هو العملية العكسية (استخراج القيمة مرة أخرى). كلاهما له تكلفة أداء (تخصيص heap، نسخ)، وفهمهما يساعدك على تجنب الحمل الزائد غير الضروري.
int number = 42; // a value type (on the stack)
object boxed = number; // BOXING — wraps 42 in an object ON THE HEAP (allocation + copy)
int unboxed = (int)boxed; // UNBOXING — extracts the value back (copy, requires a cast)
Boxing يخصص كائن جديد على الـ heap وينسخ القيمة فيه؛ unboxing ينسخها مرة أخرى. كل عملية boxing هي تخصيص heap — رخيصة مرة واحدة، لكنها مكلفة في المسارات الساخنة أو الحلقات.
// ❌ using a value type where an `object` is expected → implicit boxing
object obj = 42; // boxing
ArrayList list = new(); list.Add(42); // boxes (non-generic — stores object)
string s = string.Format("{0}", 42); // boxing for the object[] params
// these can box repeatedly in loops → significant GC pressure
Boxing يحدث غالباً بشكل ضمني — كلما تم استخدام نوع قيمة حيث يتوقع object (أو واجهة غير عامة). في الحلقات أو المسارات الساخنة، تكرار boxing ينشئ كائنات heap قصيرة الأجل كثيرة، مما يضر الأداء.
// ❌ non-generic collection — boxes every value type added
ArrayList list = new();
list.Add(42); // boxes
// ✅ generic collection — NO boxing, type-safe
List<int> list = new();
list.Add(42); // no boxing — stored as int directly
الحل الرئيسي هو استخدام الأنواع العامة (List<int> بدلاً من ArrayList) — الأنواع العامة تخزن أنواع القيم مباشرة بدون boxing. وهذا أحد الفوائد الأداء الرئيسية للأنواع العامة على المجموعات غير العامة القديمة.
فهم boxing و unboxing مهم لكتابة C# عالي الأداء ولتقدير السبب في أهمية الأنواع العامة.
Boxing — تحويل نوع قيمة إلى نوع مرجع (object) — يتكبد تخصيص heap ونسخ، و unboxing ينسخ القيمة مرة أخرى، لذا لكليهما تكلفة أداء.
بينما عملية boxing واحدة رخيصة، المشكلة هي أن boxing غالباً ما يحدث بشكل ضمني (كلما تم استخدام نوع قيمة حيث يتوقع object) ويمكن أن يحدث بشكل متكرر في الحلقات أو المسارات الساخنة، مما ينشئ كائنات heap قصيرة الأجل كثيرة تزيد ضغط GC وتضعف الأداء — مشكلة أداء دقيقة وسهلة الاشتباه بها.
المبدأ العملي الرئيسي هو أن الأنواع العامة تتجنب boxing: استخدام List<int> بدلاً من ArrayList غير العامة القديمة يخزن أنواع القيم مباشرة بدون boxing، وهذا أحد الفوائد الأداء الرئيسية للأنواع العامة على المجموعات غير العامة القديمة (والسبب الرئيسي لاستخدام المجموعات العامة دائماً).
فهم ما هو boxing/unboxing، متى يحدث (غالباً بشكل غير مرئي)، تكلفة أدائهما (تخصيص، ضغط GC، خاصة في الحلقات)، وكيف تمنعهما الأنواع العامة هو معرفة مهمة لكتابة C# فعال ولفهم السبب في تفضيل المجموعات العامة.
بما أن boxing هو مصدر شائع ودقيق لحمل الأداء الزائد، وبما أن تجنبه (عبر الأنواع العامة) ممارسة أداء أساسية، فهم boxing/unboxing معرفة قيمة وعملية ذات صلة تميز مطوري C# الواعين بالأداء وهو موضوع متكرر في المقابلات يعكس فهم نموذج نوع القيمة/المرجع وفوائد الأنواع العامة.