Dot Net For All

C# Generics – The type parameters with code example

Generic Introduction

C# is an extensible language. We can extend the functionality of a C# class by deriving from the class and overriding the virtual and abstract methods, Similarly code reuse is also one of the benefits we get out of inheritance. And C# generics also helps us to reuse the already existing code. Lets see how.

C# Generics were introduced in .NET 2.0. Generics or type parameters as they are commonly called are used to provide a place-holder for a template class in C#. We can say a generic type provides type parameters or place-holder types to be filled in by consumers of the generic type.

In C#, creation of generic Value type, reference type, delegates and interface is allowed. Generic methods are also allowed. But we cannot create generic enums and properties.

C# Generics practical example

Lets create a generic class. To create a generic class we have to create a class with type parameter as shown below.

    public class GenericList<T>
    {
        T[] list;
        int currentPos = 0;
        public GenericList(int capacity)
        {
            list = new T[capacity];
        }

        public void Add(T item)
        {
            list[currentPos++] = item;
        }

        public T Remove()
        {
            return list[--currentPos];
        }
    }

In the above code I have created a generic class named GenericList. In this class I have created an array of the type which will be passed by the user of the class at run time. GenericList class expects a type parameter T. T can be any type(value or reference) in this case. It can be any primitive type like int, bool, string or it can be any user defined type.

You can name type parameter anything you want like TIn, TOut etc. But in C# type parameters are generally named as T  by convention as interface names start with capital “I”.

Now let’s use this class in the code.

            GenericList<int> listOfIntegers = new GenericList<int>(5);
            listOfIntegers.Add(1);
            listOfIntegers.Add(2);
            listOfIntegers.Add(3);
            listOfIntegers.Add(4);
            listOfIntegers.Add(5);

In the above code I have created GenericList for integer type. I have added five integers to the list. To remove the integer we can use the below code. It will remove the last added integer from the list.

 int test = listOfIntegers.Remove();

As we can see in the above two code snippets. It is very easy to create GenericList for any type and use it.

Without Generics

We can achieve the above functionality without generics. But in the class we have to use the array of object in place of generic array as shown in the code below.

    public class GenericList
    {
        object[] list;
        int currentPos = 0;
        public GenericList(int capacity)
        {
            list = new object[capacity];
        }

        public void Add(object item)
        {
            list[currentPos++] = item;
        }

        public object Remove()
        {
            return list[--currentPos];
        }
    }

if we have to use the above class for value types it will be a performance hit. As CLR will box the value type to reference type while adding. And while retrieving the value from collection it will unbox the reference type. And after getting the value we have type cast it to use as shown in the code below.

            GenericList listOfIntegers = new GenericList(5);
            listOfIntegers.Add(1);
            listOfIntegers.Add(2);           

            object test = (int)listOfIntegers.Remove();

Benefits of Using Generics

Source code protection The developer using a generic algorithm doesn’t need to have access to the algorithm’s source code. With C++ templates or Java’s generics,however, the algorithm’s source code must be available to the developer who is using the algorithm.

Type safety When a generic algorithm is used with a specific type, the compiler and the CLR understand this and ensure that only objects compatible with the specified data type are used with the algorithm. Attempting to use an object of an incompatible type will result in either a compiler error or a runtime exception being thrown. In the example of GenericList discussed earlier, attempting to pass a String object to the Add method results in the compiler error. Check the figure below.

Compile time error

Cleaner code Since the compiler enforces type safety, fewer casts are required in your source code, meaning that your code is easier to write and maintain. In the last code snippet I have to cast the object type to int if I am not using generics.

Better performance Before generics, the way to define a generalized algorithm was to define all of its members to work with the Object data type. If you wanted to use the algorithm with value type instances, the CLR had to box the value type instance prior to calling the members of the algorithm.

Generic Methods

A generic method declares type parameters within the signature of a method. With generic methods, many fundamental algorithms can be implemented in a general-purpose way only. Here is a generic method that swaps two values of any type:

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

Swap<T> can be used as follows:

int x = 5;
int y = 10;
Swapper.Swap(ref x, ref y);

In the above code I have not provided the type parameter while calling the Swap method as CLR implicitly identifies the type parameter using the type of method parameters.

Methods and types are the only constructs that can introduce type parameters. Properties, indexers, events, fields, constructors, operators, and so on cannot declare type parameters, although they can partake in any type parameters already declared by their enclosing type.

Conclusion :

In this article I have discussed about the C# generics and their importance. I have also discussed how C# generics can be used to have a cleaner and more maintainable code.

Top career enhancing courses you can't miss

My Learning Resource

Excel your system design interview