C# Interview Questions
C# Programming
Web DevelopmentFrontendBackendGame DevQuestion 27
What are generics in C#?
Answer:
Generics in C# allow you to define classes, methods, and data structures with a placeholder for the type of data they store or use. This provides type safety and performance benefits without sacrificing flexibility and code reusability. Generics were introduced in C# 2.0 and are part of the System.Collections.Generic
namespace.
Key Features of Generics
-
Type Safety:
- Generics provide compile-time type checking, which helps catch errors early and eliminates the need for type casting.
-
Performance:
- Generics avoid the overhead associated with boxing and unboxing when using value types, leading to improved performance.
-
Code Reusability:
- Generics allow you to create reusable code components that work with any data type, reducing code duplication.
Generic Classes
A generic class uses type parameters to define the types it can work with. The type parameter is specified in angle brackets <T>
.
Example:
public class GenericList<T>
{
private T[] items;
private int count;
public GenericList(int capacity)
{
items = new T[capacity];
count = 0;
}
public void Add(T item)
{
if (count < items.Length)
{
items[count++] = item;
}
}
public T Get(int index)
{
if (index >= 0 && index < count)
{
return items[index];
}
throw new ArgumentOutOfRangeException();
}
}
// Usage
var intList = new GenericList<int>(10);
intList.Add(1);
intList.Add(2);
Console.WriteLine(intList.Get(0)); // Output: 1
var stringList = new GenericList<string>(10);
stringList.Add("Hello");
stringList.Add("World");
Console.WriteLine(stringList.Get(1)); // Output: World
Generic Methods
A generic method defines type parameters in the method signature.
Example:
public class Utilities
{
public static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
}
// Usage
int x = 1, y = 2;
Utilities.Swap(ref x, ref y);
Console.WriteLine($"x: {x}, y: {y}"); // Output: x: 2, y: 1
string str1 = "Hello", str2 = "World";
Utilities.Swap(ref str1, ref str2);
Console.WriteLine($"str1: {str1}, str2: {str2}"); // Output: str1: World, str2: Hello
Generic Interfaces
A generic interface defines type parameters that can be implemented by classes.
Example:
public interface IRepository<T>
{
void Add(T item);
T Get(int id);
}
public class Repository<T> : IRepository<T>
{
private List<T> items = new List<T>();
public void Add(T item)
{
items.Add(item);
}
public T Get(int id)
{
if (id >= 0 && id < items.Count)
{
return items[id];
}
throw new ArgumentOutOfRangeException();
}
}
// Usage
var intRepository = new Repository<int>();
intRepository.Add(1);
intRepository.Add(2);
Console.WriteLine(intRepository.Get(0)); // Output: 1
var stringRepository = new Repository<string>();
stringRepository.Add("Hello");
stringRepository.Add("World");
Console.WriteLine(stringRepository.Get(1)); // Output: World
Constraints on Generics
You can impose constraints on generic type parameters to restrict the types that can be used.
Example:
public class Utilities
{
// T must be a reference type
public static void PrintObject<T>(T obj) where T : class
{
if (obj != null)
{
Console.WriteLine(obj.ToString());
}
}
// T must have a parameterless constructor
public static T CreateInstance<T>() where T : new()
{
return new T();
}
}
Common Constraints
where T : struct
- T must be a value type.where T : class
- T must be a reference type.where T : new()
- T must have a parameterless constructor.where T : SomeBaseClass
- T must inherit fromSomeBaseClass
.where T : SomeInterface
- T must implementSomeInterface
.
Advantages of Generics
-
Type Safety:
- Generics allow you to catch type-related errors at compile time, reducing runtime errors.
-
Performance:
- Generics eliminate the need for boxing and unboxing, which improves performance for value types.
-
Code Reusability:
- Generic classes, methods, and interfaces can be used with any data type, reducing code duplication and improving maintainability.
-
Flexibility:
- Generics provide the flexibility to define data structures and algorithms that can work with any type.
Summary
Generics in C# provide a powerful way to create type-safe, reusable, and efficient code components. By using generic classes, methods, and interfaces, you can write flexible code that works with any data type while benefiting from compile-time type checking and improved performance. Constraints on generics allow you to enforce specific type requirements, further enhancing the robustness of your code.