DEV Community

Hassan BOLAJRAF
Hassan BOLAJRAF

Posted on

C# | Understanding Generics

Note
You can check other posts on my personal website: https://hbolajraf.net

Generics in C# provide a way to write flexible and reusable code by allowing the creation of classes, structures, interfaces, and methods with placeholders for data types. This enables the writing of code that works with any data type without sacrificing type safety.

Generic Classes

A generic class is a template that can work with any data type. Here's a simple example:

public class Box<T>
{
    private T value;

    public void Set(T newValue)
    {
        value = newValue;
    }

    public T Get()
    {
        return value;
    }
}

// Usage
Box<int> intBox = new Box<int>();
intBox.Set(42);
int intValue = intBox.Get();

Box<string> stringBox = new Box<string>();
stringBox.Set("Hello, Generics!");
string stringValue = stringBox.Get();
Enter fullscreen mode Exit fullscreen mode

In this example, the Box class is generic with the type parameter T. This allows creating instances of Box with different data types.

Generic Methods

Generic methods allow specifying the data type at the method level:

public class Utility
{
    public static void Swap<T>(ref T a, ref T b)
    {
        T temp = a;
        a = b;
        b = temp;
    }
}

// Usage
int num1 = 5, num2 = 10;
Utility.Swap(ref num1, ref num2);

string str1 = "Hello", str2 = "World";
Utility.Swap(ref str1, ref str2);
Enter fullscreen mode Exit fullscreen mode

In this example, the Swap method can be used to swap the values of variables of any data type.

Constraints

Generics support constraints to restrict the types that can be used. For instance, you might want to ensure that a generic type implements a particular interface:

public interface IShape
{
    double Area();
}

public class ShapeContainer<T> where T : IShape
{
    private T shape;

    public ShapeContainer(T shape)
    {
        this.shape = shape;
    }

    public double GetArea()
    {
        return shape.Area();
    }
}

// Usage
public class Circle : IShape
{
    public double Radius { get; set; }

    public double Area()
    {
        return Math.PI * Radius * Radius;
    }
}

ShapeContainer<Circle> circleContainer = new ShapeContainer<Circle>(new Circle { Radius = 5.0 });
double circleArea = circleContainer.GetArea();
Enter fullscreen mode Exit fullscreen mode

Here, the ShapeContainer class only accepts types that implement the IShape interface.

What Next?

Generics in C# are a powerful tool for creating flexible and reusable code, promoting type safety, and enhancing code maintainability.

Top comments (0)