跳到主要内容

Object, Boxing/Unboxing, Generics

Short, interview-ready summary.


Memory hook

"Object = base of all reference types; boxing = value → object; unboxing = object → value; generics = avoid boxing and get type safety"


System.Object (base type)

  • All reference types inherit from object (alias Object)
  • Value types are boxed when assigned to object

Common members

Equals(object? obj)   // equality
GetHashCode() // hash for dictionaries/hash sets
ToString() // string representation
GetType() // runtime type
  • ReferenceEquals(a, b) — same reference (or both null)
  • Override Equals and GetHashCode together; use same fields for hash

Boxing and unboxing

Boxing (value → reference)

int i = 42;
object o = i; // box: value copied to heap, o refers to box
  • Value is copied to heap; variable holds reference to box
  • Has cost (allocation, copy)

Unboxing (reference → value)

object o = 42;
int i = (int)o; // unbox: value copied from box to i
  • Must cast to exact value type; wrong type → InvalidCastException
  • Unboxing copies value out of the box

Why it matters

  • Boxing/unboxing in loops or hot paths can hurt performance
  • Generics (e.g. List<int> instead of ArrayList) avoid boxing for value types

Generics

"Generic type = type parameterized by T; no boxing for value types; type safety at compile time"

public class Cache&lt;T&gt;
{
private T? _value;
public T? Get() => _value;
public void Set(T value) => _value = value;
}

var intCache = new Cache&lt;int&gt;(); // T = int, no boxing
var strCache = new Cache&lt;string&gt;(); // T = string

Constraints

public void Copy&lt;T&gt;(T source) where T : class { }
public void Compare&lt;T&gt;(T a, T b) where T : IComparable&lt;T&gt; { }
public T Create&lt;T&gt;() where T : new() { return new T(); }
  • where T : class — reference type
  • where T : struct — value type (non-nullable)
  • where T : IComparable<T> — implements interface
  • where T : new() — parameterless constructor

Benefits

  • No boxing for List<int>, Dictionary<int, string>, etc.
  • Compile-time type safety
  • One implementation for all T

Interview one-liner

"object is the base type for reference types; value types are boxed when assigned to object. Boxing allocates and copies; unboxing requires an exact cast. Generics avoid boxing for value types and give compile-time type safety; use constraints (where T : ...) when you need to call methods on T."


Cheat sheet

object = base of ref types; value types box when assigned
Boxing = value → heap; unboxing = (T)obj, exact type
Generics = List&lt;T&gt;, no boxing, type safe
where T : class | struct | IComparable&lt;T&gt; | new()