Skip to main content

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()