Generic Type Parameters in C#: A Comprehensive Guide

In the world of programming, generic type parameters offer immense flexibility and reusability to developers. You can develop classes, methods, and interfaces that function with various data types using generic type parameters, which improves the readability, maintainability, and efficiency of your code. This article will demonstrate how to use generic type parameters in C# and explore their potential. By the end of this article, you’ll have a firm grasp on how to use generic type parameters to create more scalable and effective programs.

Generic type parameter often represent with <T> symbols. Which T stands for the type parameter, which can also be named TValue, myKey, or anything you want to replace. Below we are going to create sample codes with the usage of the generic parameters. The type parameter can be used as a type of fields, properties, method parameters, return types, and delegates in the base classes.

What is Generics Type Parameter in C#

Generic means general form, not specific. This means that you can declare a type parameter without stating a specific data type.

Using generic type parameters will allow you to define classes, properties, interface, fields, and methods without the specific data type. A type parameter act as a placeholder for a particular type specified in creating an instance of the generic type.

A generic type parameter can be declared using the code snippet format below.

MyClass<T> // where T is a type parameter

Note: T can also be named myTParam

You can choose name for your type parameter

I. Generic Class

This is how we can declare a generic class. By defining a type parameter inside an angle brackets after the class name. e.g., DataRepository<T> where T is the type parameter. You may try the code snippet below.

class DataRepository<T> { 
    public T Data { get; set; }
 }

Above, we declared a class name DataRepository with type parameter T. This type parameter can be used as a type of field, properties, method parameter, and return types. Data is a generic property in the above example since we are using a type parameter T instead of a specific data type like string, int, list, etc.

Using T as a type parameter is not required. You can give any name related to the usage of your parameter. Generally, T is used when using a single type parameter. It would be best to use a more readable type parameter name. You may learn more about type parameter naming guidelines using this link.

This how you can declared multiple type parameter in a class. See the code snippet below.

 public class UserSession<TUser, TSession>
    {
         public TUser userid { get; set; }
         public TSession session { get; set; }
    } 

II. Invoke Generic Class

To create an instance of a generic class, you can specify it using an actual type inside angle brackets. See the code snippet below, for example.

Generic class:

class DataRepository<T> { 
    public T Data { get; set; }
 }

Create an instance:

DataRepository<string> repository = new DataRepository<string>();
repository.Data = "Hello World";

Using the code snippet above, we specified that the property type is a string. T will now be replaced with a string type wherever T is used inside the class at compile-time, making the Data property a string type.

Now, we can assign any string value to the Data property. If you try to assigning different value type aside from string you may encounter an error during compile.

The following is a screenshot of a generic class usage.

Generic Type Parameters

Code:

class Program
  {
      static void Main(string[] args)
      {
          DataRepository<string> repository = new DataRepository<string>();
          repository.Data = "This is a freecode Zone!";
      }
  }
  
  public class DataRepository<T>
  {
      public T Data { get; set; }
  } 

If you prefer to use different data types you may do so using the following snippet.

Interger

DataRepository<int> repository = new DataRepository<int>();
repository.Data = 123 // Data value should be in integer

List<string>

string[] lists = { "list 1", "list 2","list 3", "list 4" };
 List<string> mylist = new List<string>(lists);
 DataRepository<List<string>> list = new DataRepository<List<string>>();
 list.Data = mylist; 

List<model>

myModel property:

public class myModel {
         public string name { get; set; }
     }
 List<myModel> modelList = new List<myModel>();
 modelList.Add(new myModel
 {
     name = "freecodespot.com"
 });
 DataRepository<List<myModel>> mymodel = new DataRepository<List<myModel>>();
 mymodel.Data = modelList;
 Console.WriteLine(mymodel.Data[0].name); 

III. Generic Fields

We can also include a generic field in a class. Below is the code snippet for a generic field in a class.

 class TestClass<T>
     {
         T _val;
  
         public TestClass(T t)
         {
             this._val = t;
         }
  
         public void Write()
         {
             Console.WriteLine(this._val);
         }
     } 

You can create an instance on this class using the code below.

 //generic field class
 TestClass<string> testClass = new TestClass<string>("freecodespot.com");
 testClass.Write(); 

Output:

freecodespot.com

IV. Generic Methods

A method using a type parameter as a return type or parameters is called a generic method. To understand more about the generic method, I’ll have some examples below.

 public static T generic_method<T>(T val)
{
     return val;
}

The method from the sample code above has the generic return type and a generic parameter type. We can invoke this method using the code below.

 string value = generic_method<string>("freecodespot");
 int intVal = generic_method<int>(123);
 decimal decVal = generic_method<decimal>(123.02M); 

We can also specify two type parameters in a generic method like this.

 public static T generic_method2<T,U>(T val,U val2)
 {
     return val;
 } 

Then invoke the method using the following code snippet.

string gen_return = generic_method2("freecodespot",123);

V. Advantages of Generics

  1. Generics increase the reusability of the code. Using Generics will allow us to construct a method that will dynamically accept different data types.
  2. Generic delegates enable type-safe callbacks without the need to create multiple delegate classes.
  3. Allows you to write type-safe code as  C# Generics are checked at the compile-time. If you use objects instead of generics, then casting to the correct type needs to be done at runtime.
  4. Using objects instead of Generics also has the problem of boxing/unboxing of value types or casting in case of reference types.

Download the source code for this tutorial from my GitHub account @coderbugzz.

Now, that you’ve learn generic type parameter in C#, you have to take a look on how to implement repository pattern ASP.NET Core.

Summary

By mastering the use of generic type parameters, you can unlock a wealth of possibilities in your C# projects. With their ability to create reusable and flexible code, generic type parameters are an invaluable tool in the modern developer’s arsenal. So, dive in, experiment, and harness the full potential of generic type parameters to elevate your C# programming skills to the next level.

We have learned that T is a type parameter used to create generic methods, property, field, interfaces, classes, and delegates that work with multiple types while still being type-safe. Hopefully, this tutorial has helped you understand more about generic in C# programming.

KEEP CODING!