Class Memory Hierarchy & Struct Boxing Traps
1Concept
Calling non-overridden `object` methods (`ToString`, `GetType`) on a struct causes immediate heap boxing. Always override `ToString`, `Equals`, and `GetHashCode` on structs to maintain zero allocation.
2Architecture Diagram
Struct without Override: struct.ToString() ──> Boxes struct onto Heap ──> Virtual dispatch (GC Allocation!) Struct with Override: struct.ToString() ──> Direct inline struct method execution (Zero GC Allocation!)
3Code Example
C# 13 & .NET 9
using System;
public struct OptimizedPoint : IEquatable<OptimizedPoint>
{
public int X;
public int Y;
public bool Equals(OptimizedPoint other) => X == other.X && Y == other.Y;
public override bool Equals(object? obj) => obj is OptimizedPoint other && Equals(other);
public override int GetHashCode() => HashCode.Combine(X, Y);
public override string ToString() => $"({X}, {Y})";
}
public class StructBoxingTrapDemo
{
public static void Main()
{
var pt = new OptimizedPoint { X = 100, Y = 200 };
Console.WriteLine($"Point: {pt.ToString()} (No boxing occurs)");
}
}4Expected Output
Point: (100, 200) (No boxing occurs)
5Key Takeaways
- ✓Always implement `IEquatable<T>` on every custom struct.
- ✓Always override `ToString()` on structs to prevent boxing.
- ✓Never call `.GetType()` on a struct in high-performance loops (use `typeof(T)`).