Open In App

Generic Constraints in C#

Last Updated : 22 Sep, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In C#, Generics allow classes, methods, interfaces and delegates to work with any data type. However, sometimes you may want to restrict the type of arguments that can be passed to a generic type. This is where constraints come in.

Generic constraints specify requirements for the type parameters in generics, ensuring only suitable types are used.

Syntax

class ClassName<T> where T : constraint{

// members using T

}

  • T: Type parameter.
  • constraint: Rule applied on T.

Why Use Constraints

Without constraints, a generic type can accept any type. Constraints help in:

  1. Restricting types: Limit type parameters to reference types, value types or specific classes/interfaces.
  2. Enabling functionality: Allow use of certain members or constructors of the type parameter.
  3. Improving type safety: Prevent invalid type substitutions at compile-time.

Types of Constraints in C#

1. where T : struct

  • Restricts T to value types (like int, double, bool, or user-defined struct).
  • Cannot be null.
  • Cannot be used with nullable value types (int?, double?).
C#
class ValueContainer<T> where T : struct {  public T Data { get; set; } } 

Use this when you want to ensure the generic type is always a non-nullable value type.

2. where T : class

  • Restricts T to reference types (class, interface, delegate, array).
  • Allows null values.
C#
class ReferenceContainer<T> where T : class {  public T Data { get; set; } } 

Useful when designing classes that should work only with objects and not primitive/value types.

3. where T : new()

  • Restricts T to types that have a public parameterless constructor.
  • Must appear last when combining multiple constraints.
C#
class Factory<T> where T : new() {  public T CreateInstance()  {  return new T(); // Safe to create instance  } } 

Helpful when you want to instantiate objects of type T inside the generic class.

4. where T : BaseClassName

  • Restricts T to types that inherit from a specific base class.
  • Allows access to members of the base class inside the generic class.
C#
class Animal { } class Dog : Animal { } class AnimalContainer<T> where T : Animal {  public T Data { get; set; } } 

Ensures only classes derived from Animal (like Dog) can be used as type arguments.

5. where T : InterfaceName

  • Restricts T to types that implement a specific interface.
  • Enables calling interface methods on the generic parameter.
C#
interface IShape {  void Draw(); } class ShapeContainer<T> where T : IShape {  public void Render(T shape)  {  shape.Draw();  } } 

Ensures all type arguments follow a specific contract.

6. Multiple Constraints

  • More than one constraint can be applied using a comma.
  • Example: Restrict T to be a reference type and must have a parameterless constructor.
C++
class Sample<T> where T : class, new() {  public T Create()  {  return new T();  } } 

Common in factory patterns where you want reference types that can be instantiated.

7. Constraints on Multiple Type Parameters

Each type parameter can have its own constraint.

C#
class Sample<T1, T2>  where T1 : class  where T2 : struct {  public T1 RefData { get; set; }  public T2 ValData { get; set; } } 

Ensures fine-grained control when working with multiple generics.

Example: Using Constraints Together

C#
using System; interface ILogger {  void Log(string message); } class ConsoleLogger : ILogger {  public void Log(string message) => Console.WriteLine(message); } class Service<T> where T : ILogger, new() {  public void Execute()  {  T logger = new T();  logger.Log("Service executed successfully!");  } } class Program {  static void Main()  {  Service<ConsoleLogger> service = new Service<ConsoleLogger>();  service.Execute();  } } 

Output
Service executed successfully! 

Note

  1. Constraints prevent misuse of generics by restricting type arguments.
  2. They make generic code more predictable and reliable.
  3. Many built-in generic collections and LINQ methods internally use constraints for safety.

Article Tags :

Explore