In this article, we’ll explore the concept of generics in C#, understand their importance, and dive deep into real-life examples to demonstrate real-world usage.
One of the things that makes C# so simple and scalable is the support for generics. Generics allow developers to write code that works with different data types while maintaining type safety and reusability.
The Generics allow us to define the placeholder for field methods parameters, etc. and it replaces the placeholder with some specific time at the compile time type checking. This prevents runtime errors and improves code quality by making it more robust and maintainable.
Suppose we are developing an application that requires us to store and manipulate distinct data types (e.g. integers, strings, or custom objects). Without generics, you may be forced to create separate collections and methods for each data type, resulting in reduced code redundancy and maintainability.
Using generics, we can create a collection or method that can work with any type of data, allowing us to create more efficient and concise code.
We can define a generic class or method by enclosing a < > type parameter (usually T, but it can be anything) in corner brackets.
Generic class Example
The below example demonstrates how we can create a generic class.
csharppublic class GenericClass<T> { public T Field; public GenericClass(T value) { Field = value; } public void Display() { Console.WriteLine(Field); } }
The class work with any type such as int, string, etc. when instantiated:
csharpvar intInstance = new GenericClass<int>(42); intInstance.Display(); // Output: 42 var stringInstance = new GenericClass<string>("Hello"); stringInstance.Display(); // Output: Hello
We can also have a generic method in a non-generic class:
csharppublic class NonGenericClass { public void Print<T>(T input) { Console.WriteLine(input); } }
We can call the generic method from the non-generic class in the following way.
csharpvar nonGeneric = new NonGenericClass(); nonGeneric.Print(123); // Output: 123 nonGeneric.Print("Generic!"); // Output: Generic!
We can restrict the types that a generic can accept using constraints. For example, we might want to limit T to classes, interfaces, or value types.
csharppublic class GenericWithConstraints<T> where T : class { public T Field; public GenericWithConstraints(T value) { Field = value; } }
The constraints ensure that only the referenced type can be used as T.
List<T>: A dynamic array that can store any type.
Dictionary<TKey, TValue>: A collection of key-value pairs.
Stack<T>: A last-in, first-out (LIFO) collection.
Queue<T>: A first-in, first-out (FIFO) collection.
Let’s demonstrate the c# list and dictionary with a code:
csharpList<int> numbers = new List<int> { 1, 2, 3, 4 }; Dictionary<string, int> ages = new Dictionary<string, int> { { "John", 30 }, { "Jane", 25 } };
Generics are widely used in C# to implement collection classes and list structures such as lists, dictionaries, and queues. These data structures can store and efficiently store the contents of any data.
The List<T> class in C# is a generic collection that can store a list of items of any type, as shown in the following code:
csharpList<int> integerList = new List<int>(); integerList.Add(1); integerList.Add(2); List<string> stringList = new List<string>(); stringList.Add("Apple"); stringList.Add("Banana");
By using the same List<T> class, you can store and work with both integers and strings.
Advantages of Generics
The following are the advantages of the generics in c#.
Type Safety: Reduces runtime errors by checking types at compile time.
Code Reuse: You can reuse code for different data types.
Performance: No need for boxing/unboxing with value types.
Copyrights © 2024 letsupdateskills All rights reserved