Understanding Generics in C#

Understanding Generics in C#

When I started my coding journey in C# and learned to create projects, I wondered if we could define classes and methods without specifying exact data types.

I got this answer when I came across Generics. This powerful feature in C# allows devs exactly what I was wondering.

Web developers must always try to reusable code instead of repeating the same code multiple times — saves time, and code becomes efficient and maintainable.

What are Generics?

So technically, generics is like a placeholder where you can define your classes, methods, or even interfaces without worrying about the type of the code until it is instantiated or invoked.

What’s best thing is, you can work with different data types without duplicating your code.

For example, consider a non-generic :

What happens here is that will allow you to store any data type — which is flexible, but what you need to understand here is that it is prone to runtime errors.

Do you know what will happen if you try to retrieve a value of the wrong type? — It will result in an exception. And this is an unwanted situation that any dev wants to tackle.

In such cases, we can take the help of generics. It eliminates this problem by ensuring type safety at compile time.

So as you can see, I have used type and if I try to add a string type into this list, I would receive a compile-time error.

Let’s look at some advantages generics has to offer:

  1. Generics ensures that any data type mismatch is resolved at compile time itself, rather than resolving at runtime.

  2. Generics avoid boxing and unboxing which reduces overhead and improves performance.

  3. It reduces code duplication.

  4. A single generic class can support multiple data types (which we will see in a bit).


Generic Classes

A generic class allows you to define a class with type params.

Here’s how it can be defined:

The here acts as a placeholder and makes the class reusable for any data type. Isn’t that great?!

The is a private field of type . It will hold the value provided during the object’s creation.

Finally in the , I have used two data types but reused the same . It creates an instance of and uses multiple data types to demonstrate code reusability.

Output


Generic Methods

Methods with type parameters are generic methods. The parameters are specified when the method is called.

Here I have taken a classic swap example that demonstrates the usage of generic methods.

The ` indicates a generic method and can operate on any data type.

and — both parameters are passed by reference ( keyword). This means the method modifies the original variables rather than working with copies.

Output


Built-in Generic Types

Did you know .NET Framework already provides several generic types and classes?

  • Collections — , , ,

  • Nullable Types —

  • Delegates and Events — , , and


Generic Interfaces

Just like normal interfaces, a generic interface also defines a contract for classes. Any class that inherits this interface must use methods declared in it.

Here’s what it would look like:

Here, is an interface that mandates all the classes that inherit this interface to implement all the methods declared in it.

In other words, this interface defines a contract for classes that inherit this.

The data type is flexible because of its type.

Output

Constraints in Generics

C# allows you to use constraints that allow restriction to specify certain types while instantiating generic types.

Using constraints, when we create a new instance of a generic type we can restrict what types we want to substitute for type parameters.

If we try to substitute a type that does not comply with the constraint we can expect a compile-time error.

We specify constraints using the clause. No, don’t worry. This is not SQL class 😉

Pay attention to the description given.

  1. — T must be a reference type.

  2. — T must be a value type.

  3. — T must have a parameterless constructor.

  4. — T must inherit from .

  5. — T must implement the specified interface.

A simple example of each that would help you understand how it is declared

Class

Struct

Default constructor using new()

BaseClass

Interface


Limitations

Despite the generic’s flexibility, it does have some limitations.

  • This code:

Is still invalid even though the string is derived from an object — strange, but true.

  • You cannot enforce operators like , , or in generics.

Ending Note

Make use of such features that C# provides to enhance your code and write efficient pieces of code. By understanding generics, you can reduce code duplication and improve app performance.

Despite its limitations, devs must use generics depending on their project requirement.

Thank you for reading! 😊

Abdulfetah Siraj

Application Support Specialist at Tata Consultancy Services

6mo

Very helpful

To view or add a comment, sign in

Others also viewed

Explore topics