C# Generics
The generic class allows users to define classes and methods using placeholders. The C# language has received generics in version 2.0. A powerful method for producing reusable code is offered by generics in C#. They enable type safety without compromising the ability to construct classes, interfaces, and methods that can operate on various data types. You can develop code that is more adaptable, effective, and simple to maintain by using generics.
- One of the collection’s main limitations is the lack of efficient type checking.
- Since all C# programming language classes extend from the object base class, any object can be included in a collection.
- The essential definition of C# as a type of safety is contradicted by this, which compromises type safety.
- Furthermore, employing collections results in a sizable performance hit due to the implicit and explicit type casting needed to add or retrieve objects from a collection.
- Generics are a feature of the.NET framework that can be used to create classes, structures, interfaces, and methods that serve as stand-ins for the types they employ to address the particular safety concern.
- Using generics while building type-safe collections of reference and value types is usual.
- Generic namespace provides the.NET framework and is also used for implementing generic collections.
Generic Class:
Generics are the most powerful feature of C#. Because it makes it possible to reuse the data processing techniques without duplicating type-specific code, this results in a notable performance improvement and high-quality code. In C++, generics are comparable to templates, but their capabilities and implementation are distinct. Since generics introduced the idea of type parameters, it is now possible to design classes and methods that frame data types after they have been declared and called by user code.
Because there is less requirement for boxing, packaging, and type casting, generic types perform better than typical system types. When a generic class is created, parameter types are given. Using the steps below, generic class objects can be created.
Example 1:
Program:
The following program will be:
// C# program to show working of
//user-defined Generic classes
using System;
// We use < > to specify Parameter type
public class JTP<T> {
// private data members
private T data;
// using properties
public T value
{
// using accessors
get
{
return this.data;
}
set
{
this.data = value;
}
}
}
// Driver class
class Test {
// Main method
static void Main(string[] args)
{
// instance of string type
JTP<string> name = new JTP<string>();
name.value = "Javatpoint";
// instance of float type
JTP<float> version = new JTP<float>();
version.value = 5.0F;
// display GeeksforGeeks
Console.WriteLine(name.value);
// display 5
Console.WriteLine(version.value);
}
}
OUTPUT:
The Output for the following program will be:
Explanation
![C# Generics](https://static.tutorialandexample.com/csharp/csharp-generics1.png)
Explanation of the following program will be:
This example creates a generic class called JTP that uses the generic type of argument "T." By substituting the data types string and 'float' for 'T' in the Main() method, two instances of JTP have been produced. Both'string' and 'float' values are kept in these objects, accordingly. By accepting the necessary type in its constructor, the JTP class guarantees type safety. A generic approach with different parameters: Generics can accept a variety of parameters, just as a method might accept one input. As seen below, one argument can be supplied as a well-known type and the other as a generic type.
Example 2:
Program:
The following program is as follows:
// C# program to show multiple
// type parameters in Generics
using System;
public class JTP {
// Generics method
public void Display<TypeOfValue>(string msg, TypeOfValue value)
{
Console.WriteLine("{0}:{1}", msg, value);
}
}
// Driver class
public class Example {
// Main Method
public static int Main()
{
// creating object of class GFG
JTP p = new JTP();
// calling Generics method
p.Display<int>("Integer", 122);
p.Display<char>("Character", 'H');
p.Display<double>("Decimal", 255.67);
return 0;
}
}
OUTPUT:
The Output for the following program will be:
![C# Generics](https://static.tutorialandexample.com/csharp/csharp-generics2.png)
A concept called generic it enables us to define classes and functions using placeholders. At compile time, the C# compiler substitutes these placeholders with the given type. Generic classes and methods are created using the generics theory.
We need angle brackets to define the generic class. Use the angle brackets to declare a class or method as a generic type. In the following example, we are developing a generic class that can be applied to any data.
Example 3:
Program:
The following program is as follows:
using System;
namespace CSharpProgram
{
class GenericClass<T>
{
public GenericClass(T msg)
{
Console.WriteLine(msg);
}
}
class Program
{
static void Main(string[] args)
{
GenericClass<string> gen = new GenericClass<string> ("This is generic class");
GenericClass<int> genI = new GenericClass<int>(101);
GenericClass<char> getCh = new GenericClass<char>('I');
}
}
}
OUTPUT:
The Output for the following program will be:
![C# Generics](https://static.tutorialandexample.com/csharp/csharp-generics3.png)
Generic methods can also be written in C#. The generic method we're developing in the example below can be called by passing any argument.
By taking a example, let's examine the necessity of generics in C#. Let's write a brief program to determine if two integer values are equal—the implementation of the code that follows a simple code. With the names ClsMain and ClsCalculator, we built two classes in this instance. A function called AreEqual() within the ClsCalculator class determines whether two integer values are equal or not after receiving two input parameters.
Example 4:
Program:
The following program is as follows:
using System;
namespace GenericsDemo
{
public class ClsMain
{
private static void Main()
{
bool IsEqual = ClsCalculator.AreEqual(10, 20);
if (IsEqual)
{
Console.WriteLine("Both are Equal");
}
else
{
Console.WriteLine("Both are Not Equal");
}
Console.ReadKey();
}
}
public class ClsCalculator
{
public static bool AreEqual(int value1, int value2)
{
return value1 == value2;
}
}
}
OUTPUT:
The Output for the following program will be:
![C# Generics](https://static.tutorialandexample.com/csharp/csharp-generics4.png)
Example 5:
The following program is as follows:
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>("Preethi");
//Create an instance with data type int
Student<int> studentId = new Student<int>(23);
}
}
OUTPUT:
The Output for the following program will be:
![C# Generics](https://static.tutorialandexample.com/csharp/csharp-generics5.png)
Instantiating Generic Class:
Generic classes can be created by including an actual type in angle brackets. The generic class DataStore can be created using the following syntax:
DataStore<string> store = new DataStore<string>();
In the example above, we created an instance while specifying the string type in the angle brackets. As a result, wherever T is used across the entire class at compile time, a string type will be substituted for it. So, a string would be the Data property's type.
The Data property can have a string value assigned to it. A compile-time error will appear if you attempt to assign anything besides strings.
DataStore<string> store = new DataStore<string>();
store.Data = "Hello World!";
//store.Data = 123; //compile-time error
Employ generic types to increase performance, type safety, and code reuse. The creation of collection classes is the most popular application of generics. The System of the NET class library contains a number of generic collection classes.
Features of Generics:
Generics is a method that enhances your programs in different ways, including:
- It supports type safety, performance, and code reuse.
- Your generic custom classes, methods, interfaces, and delegates are possible.
- Generic collection classes can be made by numerous new generic collection classes and it may be found in System.Collections.Generic namespace of the.NET framework class library.
- You can learn more about the kinds which can be utilised in generic data types at runtime.
- You can maximize efficiency, type safety, and code reuse with its help.
- Generic collection classes can be made, on numerous new System generic collection classes exist in the.NET Framework class library for System.Collections.Generic namespace.
- You can use these generic collection classes for the System—collections namespace in place of the System's collection classes.
- You can create your generic classes, methods, programs, and delegates.
- At runtime, reflection can be used to obtain details about the types that went into creating a generic data type.
Generic class Characteristics:
- The reusability is increased with a generic class. It becomes more reusable among the more type of parameters.
- However, excessive generalization makes it challenging to comprehend and maintain code.
- A generic class may serve as the foundation for abstract and generic or non-generic classes.
- A generic class may be descended from abstract classes, generic classes, or other classes, generic or not.
Common Use cases:
In several situations, including the following, generics are widely used:
1. Collections: The efficient storage and processing of various types of data is made possible by generic collections like List<T>, Dictionary<TKey, TValue>, and Queue<T>.
2. Algorithms: Sorting and searching are examples of generic algorithms that may be implemented once and used with a variety of data types.
3.Custom Data Structures: Generics can be used to design unique data structures, such as linked lists, stacks, and trees, that can handle any type.
4.Database Operations: You can use generics in database access layers to provide reusable code for various sorts of data manipulation and querying.
Advantages of Generics:
- Reusability:
A single generic type of declaration can serve various functions in the same bit of code without requiring any changes. You can develop a general way to add two numbers, for instance. This function can add two floats and two integers without changing the code.
- Type-Safety:
Particularly regarding collections, generic data types offer superior type safety. The kind of objects that will be supplied to a collection when utilizing generics must be specified. This aids the compiler in ensuring that the collection may accept just the object types defined in the definition.
- Performance:
Generic types outperform conventional system types because there is less need for boxing, unpacking, and typecasting of variables and objects.
- Generics make the code more reusable. You don't need to write any code to handle various data kinds.
- Type-safe generics can be used. Compile-time issues arise if you try to utilise a different data type than what is specified in the definition.
- Because boxing and unpacking are not an option, generic has a performance benefit.
Conclusion:
The C# language's generics feature enables the construction of parameterized types, which facilitates the creation of reusable code. It allows us to develop classes, interfaces, and methods that interact with several data types without explicitly defining each one.
- We may create code that is more adaptable and has fewer errors by using generics. For instance, we may create a single function that handles several data kinds rather than creating distinct methods for each type.
- Utilizing generics offers type safety, which is its fundamental advantage. The type of parameter that can be used with a generic class, interface, or function can be specified when those elements are defined.
- This assures that only data types match the type parameter and that it will be accepted and used by the code, avoiding problems that may arise from data type mismatches.
- As it is feasible to create a generic class or method that may operate on any data type rather than creating numerous methods or classes for various data types, generics can also assist in eliminating code duplication.
- There are several built-in generic types available in C#, including List<T>, Dictionary<TKey, TValue>, and NullableT>. The Syntax <T> allows us to design generic classes, interfaces, and methods.
Generics are a vital C# feature that makes writing flexible, reusable, type-safe code that can operate on various data types easier. Using generics, you may design flexible, practical algorithms and data structures that work with various data types. Generics further enhance type safety by catching type-related mistakes at compile time rather than at runtime.
To ensure that the generic code may access a specific member of the type argument or satisfy certain criteria, constraints can be imposed on type parameters. This helps to create more robust and reliable code. You can develop reusable and type-safe code using C#'s powerful generics feature. Generics help you increase code reuse, boost performance, and guarantee type safety. You can build more adaptable and maintainable applications by understanding and using generics properly.