Under Construction
Unity14 min237 views

Boxing c#

Minh Khoa

Minh Khoa

Author

image.png# 🎯 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 “intstring)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