CodeBlanks Logo Icon CodeBlanks

Generics vs object

C# course · Intermediate · Lesson 74/116

Learn the type-safety difference between generics and object.

The non-generic alternative: object

In C# object is the base of all types. If you make a property of type object it can hold any value: public object Value { get; set; }. But this approach has a big problem: boxing and required casts.

For example, an int value is boxed when assigned to object; you need an (int) cast to get it back. Casting to the wrong type throws InvalidCastException. Generic classes solve this at the root: Box<int> has no boxing, no casts and errors are caught at compile time.

The hidden cost of boxing

Assigning an int to object is not just syntax; it is a memory event. The value type is boxed on the heap instead of living on the stack. This means extra allocation and copying. Done many times, it slows the program down.

Generic classes avoid boxing: the int inside Box<int> sits directly in the property. This is why List<int> is much faster than the old ArrayList. Generics give type safety and performance at once.

Exercise Compare ObjectBox and Box<T>

Define an ObjectBox class with public object Value { get; set; }. Define a Box<T> generic class with public T Value { get; set; }. In Main create an ObjectBox, set Value = 42, get it back with an (int) cast and print. Do the same with Box<int>; print without a cast.

Show example solution
Write class ObjectBox { public object Value { get; set; } } and class Box<T> { public T Value { get; set; } }. In Main add var ob = new ObjectBox { Value = 42 }; int n = (int)ob.Value; Console.WriteLine(n); var gb = new Box<int> { Value = 42 }; Console.WriteLine(gb.Value);
Example solution:
using System;

class ObjectBox
{
    public object Value { get; set; }
}

class Box<T>
{
    public T Value { get; set; }
}

class Program
{
    static void Main()
    {
        var ob = new ObjectBox { Value = 42 };
        int n = (int)ob.Value;
        Console.WriteLine(n);

        var gb = new Box<int> { Value = 42 };
        Console.WriteLine(gb.Value);
    }
}

Test yourself

  1. Match each approach to its trait

    object
    Requires boxing
    <T>
    Type safe
    (int) cast
    Runtime risk
    compile error
    Generic guarantee
  2. What is needed to get int back from object?

    object o = 42;
    int n = ______;
    • Cast (int)o
    • Nothing, n = o
    • Boxing operator
    • new int(o)
    Show answer

    Cast (int)o — Correct. (int) cast is needed to unbox from object.

  3. The object property

    public ____ Value { get; set; } // requires boxing
    Show answer
    public object Value { get; set; } // requires boxing

All lessons in Intermediate