Skip to main content

How to Resolve Error "CS0450: Cannot specify both a constraint class and the 'class' or 'struct' constraint" in C#

The Compiler Error CS0450 is a syntax error regarding Generic Type Constraints. The message reads: "'Type Parameter Name': cannot specify both a constraint class and the 'class' or 'struct' constraint".

In C#, generic constraints allow you to restrict what types can be passed to a generic class or method. The Primary Constraint defines the fundamental nature of the type (e.g., "It must be a value type" or "It must inherit from this specific Class"). The language rules state you can have only one primary constraint.

Since specifying a Base Class (e.g., MyClass) automatically implies that T is a reference type, adding the generic class constraint is redundant. Similarly, adding the struct constraint creates a logical contradiction (a type cannot be a struct and inherit from a specific class).

Understanding Constraint Redundancy

When you write where T : MyBaseClass, the compiler infers specific rules:

  1. T must be or derive from MyBaseClass.
  2. Since MyBaseClass is a class, T must be a reference type.

Because rule #2 is implied by rule #1, explicitly adding the class keyword (where T : class) adds no new information and violates the syntax rule allowing only one primary constraint.

Scenario 1: Combining Base Class with class

This is the most common cause. You want to ensure T is a class and also a specific type, so you list both.

Example of error

public class User { }

// ⛔️ Error CS0450: 'T': cannot specify both a constraint class and the 'class' constraint.
// 'User' IS a class. Adding 'class' is redundant and invalid.
public class Repository<T> where T : User, class
{
}

Solution: Remove class

Simply specifying the base class is sufficient to enforce that T is a reference type.

public class User { }

// ✅ Correct: 'T' is constrained to be 'User' or a subclass of 'User'.
// This implies it is a reference type.
public class Repository<T> where T : User
{
}
note

If T can be any class, use where T : class. If T must be a specific class, use where T : SpecificClass. You never need both.

Scenario 2: Combining Base Class with struct

This scenario represents a logical impossibility. You are asking the compiler for a type that inherits from a specific Class (Reference Type) but is also a Struct (Value Type).

Example of error

public class Entity { }

// ⛔️ Error CS0450: 'T': cannot specify both a constraint class and the 'struct' constraint.
// A struct cannot inherit from 'Entity'.
public class Manager<T> where T : Entity, struct
{
}

Solution: Choose One

You must decide if your generic type is meant to be a Value Type or a Reference Type.

Option A: Enforce Value Type If T must be a struct, remove the base class constraint (structs cannot inherit). You can use Interfaces instead.

public interface IEntity { }

// ✅ Correct: T is a struct that implements an interface
public class Manager<T> where T : struct, IEntity
{
}

Option B: Enforce Hierarchy If T must inherit logic from Entity, it cannot be a struct.

public class Entity { }

// ✅ Correct: T is a class inheriting from Entity
public class Manager<T> where T : Entity
{
}

Conclusion

CS0450 keeps your generic definitions clean and logical.

  1. Redundancy: where T : MyClass implies class. Don't write class explicitly.
  2. Contradiction: A type cannot be a struct and inherit from a custom Class at the same time.
  3. Fix: Remove the generic keyword (class or struct) and rely on the specific Base Class name to define the constraint.