C# Generics allow us to create a single class or method that can be used with different types of data. This helps us to reuse our code.
Here, we will learn to create generics class and method in C#.
C# generics Class
A generics class is used to create an instance of any data type. To define a generics class, we use angle brackets (<>
) as,
class Student<T>
{
// block of code
}
Here, we have created a generics class named Student
. T
used inside the angle bracket is called the type parameter.
While creating an instance of the class, we specify the data type of the object which replaces the type parameter.
Create an Instance of Generics Class
Let's create two instances of the generics class.
// create an instance with data type string
Student<string> studentName = new Student<string>();
// create an instance with data type int
Student<int> studentId = new Student<int>();
Here, we have created two instances named studentName
and studentId
with data types string
and int
, respectively.
During the time of compilation, the type parameter T
of the Student
class is replaced by,
string
- for instancestudentName
int
- for instancestudentId
Example: C# generics Class
using System;
// define a generics class named Student
public class Student<T>
{
// define a variable of type T
public T data;
// define a constructor of the Student class
public Student(T data)
{
this.data = data;
Console.WriteLine("Data passed: " + this.data);
}
}
class Program
{
static void Main()
{
// create an instance with data type string
Student<string> studentName = new Student<string>("Avicii");
// create an instance with data type int
Student<int> studentId = new Student<int>(23);
}
}
Output
Data passed: Avicii Data passed: 23
In the above example, we have created a generics class named Student
. Also, we have defined a constructor that prints this
value.
Inside the Main
class, we have created two instances of the Student
classes: studentName
and studentId
.
The type parameter T
of Student<T>
is replaced by:
string
- instudentName
int
- instudentId
Here, the Student
class works with both the int
and the string
data type.
C# generics Method
Similar to the generics class, we can also create a method that can be used with any type of data. Such a class is known as the generics Method. For example,
public void displayData(T data) {
Console.WriteLine("Data Passed: " + data);
}
Here,
displayData
- name of the generics methodT
- type parameter to specify the function can accept any type of datadata
- function parameter
Now we can use this function to work with any type of data. For example,
// calling function with integer data
obj.displayData(34);
// calling function with string data
obj.displayData("Tim");
Example: C# generics Method
using System;
// define a generics class named Employee
class Employee<T>
{
// define a generics method that displays the passed data
public void displayData(T data)
{
Console.WriteLine("The data passed is: " + data);
}
}
class Program
{
static void Main()
{
// create an instance of Employee class by specifying T as string
Employee<string> employeeName = new Employee<string>();
// call displayData() generics method and pass a string value - "Jack"
employeeName.displayData("Jack");
// create an instance of Employee class by specifying T as int
Employee<int> employeeId = new Employee<int>();
// call displayData() generics method and pass an integer value
employeeId.displayData(123);
}
}
Output
The data passed is: Jack The data passed is: 123
In the above example, we have defined a generics method named displayData()
inside the Employee<T>
generics class.
Example: Generics Method with Return Type
Earlier we defined a generics method without a return type. However, we can also define a generics method with a return type. For example,
using System;
// define a generics class named Employee
class Movie<T>
{
// define a generics method that returns T type value
public T displayData(T data)
{
return data;
}
}
class Program
{
static void Main()
{
// create an instance with data type string
Movie<string> movieName = new Movie<string>();
Console.WriteLine("Generics Method returns: " + movieName.displayData("Inception"));
// create an instance with data type int
Movie<int> movieRating = new Movie<int>();
Console.WriteLine("Generics Method returns: " + movieRating.displayData(9));
}
}
Output
Generics Method returns: Inception Generics Method returns: 9
In the above example, we have created a generics method named displayData()
. Notice that, we have used T
as a return type instead of void.
This means the method can return a value of any type.
public T displayData(T data) {...}
In our case, the method is returning,
string
data -"Inception"
int
data - 9
Advantages of Generics
1.Code Reusability
With the help of generics in C#, we can write code that will work with different types of data. For example,
public void displayData(T data) {...}
Here, we have created a generics method. This same method can be used to perform operations on integer data, string data, and so on.
2.Compile-time Type Checking
The type parameter of generics provides information about the type of data used in the generics code. For example,
// int type instance of GenericsClass
GenericsClass<int> list = new GenericsClass<>();
Here, we know that GenericsClass
is working with int
data only.
Now, if we try to pass data other than int
to this class, the program will generate an error at compile time.
3.Used with Collections
The collections framework uses the concept of generics in C#. For example,
// create a string type List
List<string> courseName = new List<string>();
// create an int type List
List<int> courseId = new List<int>();
In the above example, we have used the same List
class to work with different types of data.
Similar to List
, other collections (Queue
, Stack
, and so on) are also generic in C#.
Frequently Asked Questions
We can also define a generics method inside a non-generics class. For example,
using System;
// create a non-generic class named Gadget
public class Gadget
{
// define a generic method
public T displayData<T>(T data)
{
return data;
}
}
class Program
{
static void Main()
{
Gadget gadgetName = new Gadget();
// call generic method displayData() and pass string data
Console.WriteLine("Generic Method returns: " + gadgetName.displayData("Laptop"));
Gadget gadgetModel = new Gadget();
// call generic method displayData() and pass integer data
Console.WriteLine("Generic Method returns: " + gadgetModel.displayData(513));
}
}
Output
Generic Method returns: Laptop Generic Method returns: 513
In the above example, we have created a generic method named displayData()
inside the non-generic class named Gadget
. Notice the code,
public T displayData<T>(T data) {...}
Here, we need to use <T>
to define a generics method displayData()
without a generics class.
In C#, we can also create generics properties. For example,
using System;
public class Sport<T>
{
// define a generic field
public T data;
// define a generic property
public T Data
{
get { return data; }
set { data = value; }
}
}
class Program
{
static void Main()
{
// create an instance of Sport with data type string
Sport<string> sportName = new Sport<string>();
// access the generic property, Data
sportName.Data = "Football";
Console.WriteLine("Name of Sport is : " + sportName.Data);
}
}
Output
Name of Sport is : Football
Here, we have defined a generics property named Data
.
Note: Not only to property, class or methods, we can also use generics with abstract class, interface, events, delegates, and so on.