Boxing c#
Minh Khoa
Author
# 🎯 1. What is boxing? (standard definition)
Boxing = the action of converting a value of a value type (int, float, bool, struct…) into an object (of a reference type).
That is, C# packs the value into an “object box” on the heap.
Example:
int x = 5;
object obj = x; // ← boxing xảy ra
x from a value type (stored on the stack) → copied into an object (stored on the heap).
🎯 2. What is unboxing?
Taking the value out of the object:
object obj = 10;
int y = (int)obj; // ← unboxing
🎯 3. Why is BOXING harmful in Unity?
❌ (1) Boxing creates memory allocation → causing GC
When boxing, C# creates a new object on the heap.
→ Alloc
→ Then GC must be collected → causing spikes, drops FPS.
In games, especially in the update loop → very dangerous.
❌ (2) Happens implicitly → hard to detect
Example:
int x = 10;
Debug.Log(x);
There is boxing because Log receives the parameter as object.
❌ (3) Boxing happens when using an interface
If a struct implements an interface → calling the interface method → BOX.
public interface IAttack { void Do(); }
public struct Sword : IAttack
{
public void Do() { }
}
IAttack atk = new Sword(); // boxing!
❌ (4) Boxing when using a generic without good constraints
Example:
void Print<T>(T value)
{
Debug.Log(value); // boxing nếu value là struct
}
❌ (5) LINQ often causes boxing
LINQ to Object creates delegates, iterators → allocation + boxing.
🎯 4. Some common boxing examples in Unity
❌ Example 1: Debug.Log
int score = 10;
Debug.Log(score); // boxing
How to fix:
Debug.Log($"{score}"); // không boxing (string format)
❌ Example 2: Struct in List<object>
List<object> list = new();
list.Add(5); // boxing
❌ Example 3: Using an interface with a struct
IMovement mover = new MovementStruct(); // boxing
❌ Example 4: foreach with a struct enumeration
foreach (var item in myStructList) { ... }
// nếu enumerator là struct → có thể boxing tùy implement
❌ Example 5: Event with a struct argument
Action<MyStruct> onChange;
onChange(myStruct); // có thể boxing
🎯 5. How can boxing be avoided?
✔ 1. Avoid using object to hold a value type
Wrong:
object obj = 5;
Correct:
int x = 5;
✔ 2. Avoid interfaces if the struct implements an interface
Use generics instead.
*Generic (or general programming) is not a specific data type (such as “, but “int, string)is the concept of parameterized data types “**parameterized types(. It allows defining classes)**class (, interfaces)interface (and methods) method (with unspecified data types, helping source code remain flexible, highly reusable, and tightly controlled for errors at compile time) Wrong:
Correct:
IAttack atk = new Sword();
→ cast to string to avoid boxing
void Perform<T>(T atk) where T : IAttack
{
atk.Do();
}
✔ 3. Debug.Log ✔ 4. Optimize systems that use structs
Debug.Log(score.ToString());
job system, (/ Burst completely ECS)
ECS no boxing ✔ 5. Avoid boxing in Dictionary key.
If the key is a struct → boxing may occur when
the override is poor. GetHashCode() 6. How do you know if there is boxing in the code?
🎯 Unity Editor:
Turn on
- Profiler → Alloc. ]}]}]}]}]}]}]} ]}]}]}]}]}]}]}]},{ GC content_segments of json from above
- Or enable Deep Profile
If each frame has:
System.Object
System.Int32
System.ValueType
→ that's BOXING.
🎯 7. Super easy-to-remember summary
BOXING = struct → object → creates garbage → causes GC → drop FPS
What Unity fears most GC → avoid boxing in:
- Update()
- LateUpdate()
- FixedUpdate()
- UI event spam
- DOTS / Jobs
- Network serialization