Generics in C# are types that make a single class or function cater to various data type members. With generics, we can make our code much more efficient, since we only have to implement a single umbrella function or class in our program.
Generic classes are defined using the following syntax:
public class ClassName<T>{T memberName;//... class methods implementation}
The <>
tag specifies that the class is generic and caters to multiple data types. Built-in data types (int
, char
, string
, double
, and so on) as well as user-defined data types can be passed into this class as parameters.
The <T>
allows different kinds of data types to be passed as parameters, as specified by the user. Also, it sets the data types of the data members defined using the T
keyword according to the parameterized data type.
Generic methods have the following syntax:
functionType functionName<T> (T arg){//function code}
To make a function generic, we need to specify the function type (void
, int
, char
, and so on). After that, we use the same <>
tags to allow generic parameters into the function. Any word/character that is inside the <>
tags, and is also present as a data type, is used to specify that a given parameter is generic.
The following examples help us understand generic classes better:
using System;class HelloWorld{//Generic classpublic class Object<T>{public T member;public Object(T data){member = data;}}//Student classpublic class Student{public string name;public Student(){name = "Random";}public void print(){Console.WriteLine(name);}}static void Main(){//string type data member of class ObjectObject<string> example = new Object<string>("Hello world!");Console.WriteLine(example.member);//int type data member of class ObjectObject<int> example2 = new Object<int>(10);Console.WriteLine(example2.member);//double type data member of class ObjectObject<double> example3 = new Object<double>(15.55);Console.WriteLine(example3.member);//char type data member of class ObjectObject<char> example4 = new Object<char>('H');Console.WriteLine(example4.member);//Student type data member of class ObjectStudent studentExample = new Student();Object<Student> example5 = new Object<Student>(studentExample);example5.member.print();}}
Lines 5–10: We implement the generic class Object
. It has a generic type attribute named member
and a parametric constructor that initializes member
with the value passed at the time of instantiation.
Lines 25–26: We make the Object
cater to string
type. The <T>
tag catches the string
type and sets member'
s value to Hello world!
.
Lines 41–43: We create a new instance of the class Student
. After that, we create a new instance of the class Object
that caters to the type Student
. The member
attribute is initialized with the studentExample
object's value (Random
).
using System;class HelloWorld{static void print<T>(T arg){Console.WriteLine(arg);}static void Main(){int x = 0;print<int>(x);double y = 9.99;print<double>(y);char z = 'H';print<char>(z);string m = "Hello World!";print<string>(m);}}
Lines 5–7: We made the generic print()
function to cater to multiple built-in data types. It takes in any built-in data type parameter and prints data according to it.
Line 10–17: We call the print
function for different data types.
Generics is a crucial concept in C# that programmers can use to code efficiently and to write a template program that works for multiple data types. The above code snippets are good examples to show how generic classes and functions work in C#.
Free Resources