Generics in C#

 

1 - What are Generics in C#

Generics is a feature provided by .NET which allows us to create reusable code across multiple entities. 

When we write generic code, we do so to make it compatible with any data type and thus "safe" for different types. 

 

2 - Example of Generics in C#

The simplest way to demonstrate generics is by using sample code.

To do this, I’ll use code presented in a technical interview test, which fits perfectly for our purposes.

In that interview, I had to perform several API calls and return the result if everything was correct. For example, there was an option get/{id} which returned a Persona object.

For that, I used a class called OperationResult which contained 3 properties.

  • Bool Success 
  • List<string> mensageList
  • Persona Persona

Wrapping objects within another can help if we have an application reading from our API. This way, we make things easier for the client.

public class OperationResult 
{
    public bool Success => !MessageList.Any();
    public List<string> MessageList { get; private set; }
    public Persona Persona { get; set; }

    public OperationResult()
    {
        MessageList = new List<string>();
    }

    public void AddMessage(string message)
    {
        MessageList.Add(message);
    }

    public void SetSuccesResponse(Persona pers)
    {
        Persona = pers;
    }   
}

 At the same time, we have another endpoint that must return a Coche object.

public class OperationResultCars
{
    public bool Success => !MessageList.Any();
    public List<string> MessageList { get; private set; }
    public Car Coche { get; set; }

    public OperationResult()
    {
        MessageList = new List<string>();
    }

    public void AddMessage(string message)
    {
        MessageList.Add(message);
    }

    public void SetSuccesResponse(Car coche)
    {
        Coche = coche;
    }
}

As we can see, both objects are practically identical, so we are repeating a lot of code. In our specific example, we are repeating 21 out of 23 lines of code, which means we are not following the "don’t repeat yourself" principle.

 

3 - Converting Our Code to Generic in C#

To convert our code to generic, we need to replace the differing code with its "generic" counterpart. Looking at the two previous examples, we only need to "merge" the Persona and Car types. 

However, these types must still exist within our object, as we will need them.

For this, we convert the previous class as follows:

public class OperationResult <T>
{
    public bool Success => !MessageList.Any();
    public List<string> MessageList { get; private set; }
    public T Response { get; set; }

    public OperationResult()
    {
        MessageList = new List<string>();
    }

    public void AddMessage(string message)
    {
        MessageList.Add(message);
    }

    public void SetSuccesResponse(T obj)
    {
        Response = obj;
    }   
}

As we can see, there is only one main difference: we have now turned the Persona and Car types into the T type immediately after the class name, making our class generic.

generics en c#

By convention, any programmer working with generics will use the letter T to indicate the type.

Finally, note that the T type will accept any type, either one created by us such as the Persona class or type, or a type such as string

 

3.1 - Multiple Types in a Generic Class in C#

Of course, we can implement more than one type in our generic class. To do this, we must pass more than one type next to the class name.

public class OperationResult <T, U>
{
    //Code
}

Still, by convention, when we introduce more than one type, we should use more than one letter to make things easier for programmers who come after us. 

public class OperationResult <TEntrada, TSalida>
{
    //Code
}

 

4 - Using a Generic Class

When we implement a generic class, we implement a type. That means, when we instantiate the generic class, we must indicate which type we’re going to use. To do this, we instantiate the variable as follows:

OperationResult<Car> optResult = new OperationResult<Car>();

Remember that T inside our class accepts any type, so it works for the Car class, Persona class, etc. 

 

5 - Generic Methods in C#

Classes are not the only parts that can be generic in our code; we can also make methods generic. To do this, we have two options

A - Generic Method in a Generic Class 

First, we can have a method that receives a parameter T or returns a parameter T, which is perfectly valid, as shown in the previous example:

public void SetSuccesResponse(T obj)
{
    Response = obj;
}

B - Generic Method in a Non-generic Class 

If we have a non-generic class, we can create a method that accepts generic types. These are less common but are occasionally seen, especially in base classes. 

To have a generic method in a non-generic class, we do it as follows:

public class Ejemplo{
    public T GenericMethod<T>(T receivedGeneric)
    {
        return receivedGeneric;
    }  
}

We indicate <T> after the method name.

And as we can see, we can also return the same type.

 

6 - Tips for Generics in C#

  • We should use Generics to create reusable code and classes or methods that are not tied to specific types. But we need to be careful, because if a class will not be reused, we should NOT make it generic as it adds a lot of complexity to our code. 
  • We should use the letter T when we have only one type parameter, but if we have more than one, it should have a more descriptive name.
  • Despite this, we should name parameters starting with T, to indicate to those reading our code that it represents a Type

 

7 - Constraints on Types

When declaring a generic class or method, we can extend the condition for the type of object we are going to use as a type.

To do so, we use the where T : {constraint} clause.

public interface IExample {}
public class Example : IExample{}

public class EjemploGeneric <T>
where T : struct //value type 
where T : class // reference type
Where T : new() //parameterless constructor
Where T : IExample //Specific interface
Where T : Example //a specific class
{

}

We can introduce constraints for all the types we use, and we can also include several constraints for a single type. For example, IExample, new() will require you to specify a class that implements IExample and also has a parameterless constructor. 

Conclusion

  • We’ll use Generics as a way or technique to define multiple data types with a single variable. 
  • This allows us to create reusable code in a safe way, and it works with any type of data.
  • Highly recommended to use generics as much as possible, but wisely, because while improving the quality of our code we can also add a certain difficulty. 
This post was translated from Spanish. You can see the original one here.
If there is any problem you can add a comment bellow or contact me in the website's contact form

Uso del bloqueador de anuncios adblock

Hola!

Primero de todo bienvenido a la web de NetMentor donde podrás aprender programación en C# y .NET desde un nivel de principiante hasta más avanzado.


Yo entiendo que utilices un bloqueador de anuncios como AdBlock, Ublock o el propio navegador Brave. Pero te tengo que pedir por favor que desactives el bloqueador para esta web.


Intento personalmente no poner mucha publicidad, la justa para pagar el servidor y por supuesto que no sea intrusiva; Si pese a ello piensas que es intrusiva siempre me puedes escribir por privado o por Twitter a @NetMentorTW.


Si ya lo has desactivado, por favor recarga la página.


Un saludo y muchas gracias por tu colaboración

© copyright 2025 NetMentor | Todos los derechos reservados | RSS Feed

Buy me a coffee Invitame a un café