Generic Classes in C#
What are Generic Classes in C#?
A Generic Class in C# allows defining a class with a placeholder for a data type. It enables code reusability, type safety, and better performance by avoiding unnecessary type casting.
Key Features of Generic Classes
- Allows defining a class with a type parameter (
T
). - Ensures type safety at compile-time.
- Prevents boxing and unboxing, improving performance.
- Supports code reusability by working with different data types.
Example: Creating and Using a Generic Class
The following example demonstrates how to create and use a generic class.
Example: Generic Class Implementation
using System;
public class GenericContainer
{
private T data;
public void SetData(T value)
{
data = value;
}
public T GetData()
{
return data;
}
}
// Usage
class Program
{
static void Main()
{
GenericContainer intContainer = new GenericContainer();
intContainer.SetData(10);
Console.WriteLine(intContainer.GetData()); // Output: 10
GenericContainer stringContainer = new GenericContainer();
stringContainer.SetData("Hello, Generics!");
Console.WriteLine(stringContainer.GetData()); // Output: Hello, Generics!
}
}
In this example, GenericContainer<T>
is a generic class that can store any data type.
Generic Classes with Multiple Type Parameters
A generic class can have multiple type parameters to store different types of data.
Example: Multiple Type Parameters
public class Pair
{
public T1 First { get; set; }
public T2 Second { get; set; }
public Pair(T1 first, T2 second)
{
First = first;
Second = second;
}
public void Display()
{
Console.WriteLine($"First: {First}, Second: {Second}");
}
}
// Usage
class Program
{
static void Main()
{
Pair student = new Pair("Alice", 25);
student.Display(); // Output: First: Alice, Second: 25
}
}
Here, the Pair<T1, T2>
class can store two different types of values.
Constraints in Generic Classes
Constraints restrict the types that can be used as generic parameters, ensuring compatibility with specific functionalities.
Constraint | Description | Example |
---|---|---|
where T : struct |
Only value types are allowed. | public class Test |
where T : class |
Only reference types are allowed. | public class Test |
where T : new() |
Type must have a parameterless constructor. | public class Test |
where T : BaseClass |
Type must inherit from a specific class. | public class Test |
where T : IInterface |
Type must implement a specific interface. | public class Test |
Example: Generic Constraint with Interface
The following example enforces that only objects implementing an interface can be used.
Example: Using Constraints
interface IDisplayable
{
void Display();
}
public class Product : IDisplayable
{
public string Name { get; set; }
public void Display()
{
Console.WriteLine($"Product: {Name}");
}
}
public class GenericDisplay where T : IDisplayable
{
private T item;
public GenericDisplay(T item)
{
this.item = item;
}
public void Show()
{
item.Display();
}
}
// Usage
class Program
{
static void Main()
{
Product product = new Product { Name = "Laptop" };
GenericDisplay display = new GenericDisplay(product);
display.Show(); // Output: Product: Laptop
}
}
Here, the GenericDisplay<T>
class only accepts types that implement IDisplayable
.