Skip to main content

How to Resolve Error "CS0401: The new() constraint must be the last restrictive constraint specified" in C#

The Compiler Error CS0401 is a syntax error regarding Generic Constraints. The message reads: "The new() constraint must be the last restrictive constraint specified".

In C#, when you define constraints on a generic type parameter (using the where keyword), the language enforces a strict ordering. You cannot list the new() constraint (which requires a public parameterless constructor) before class constraints, interface constraints, or struct/class keywords. The new() constraint must always be the very last item in the list.

This guide explains the correct order of generic constraints and how to fix this syntax error.

Understanding Constraint Ordering

C# requires generic constraints to appear in the following specific order:

  1. Primary Constraint (Optional, Max 1):
    • A Base Class name (e.g., MyBaseClass).
    • class, struct, notnull, or unmanaged.
  2. Secondary Constraints (Optional, Unlimited):
    • Interface names (e.g., IDisposable, IEnumerable<T>).
    • Type parameters (e.g., U).
  3. Constructor Constraint (Optional, Max 1):
    • new()

CS0401 occurs if you place item #3 (the new() constraint) before item #1 or #2.

Scenario: Placing new() Before Interfaces

This is the most common mistake. You want a type that implements an interface and has a constructor, so you type them in the order they came to mind.

Example of error:

public interface IWorker
{
void DoWork();
}

// ⛔️ Error CS0401: The new() constraint must be the last restrictive constraint specified.
// The compiler expects interfaces (IWorker) to be listed BEFORE 'new()'.
public class Factory<T> where T : new(), IWorker
{
public T Create()
{
return new T();
}
}

Solution: Reorder the Constraints

To fix the error, simply move the new() keyword to the end of the where clause list.

Solution:

public interface IWorker
{
void DoWork();
}

// ✅ Correct: Interface first, new() last.
public class Factory<T> where T : IWorker, new()
{
public T Create()
{
return new T();
}
}

Complex Examples (Class + Interface + new)

If you have multiple constraints, such as a Base Class, multiple Interfaces, and the constructor constraint, the order must be strictly maintained.

Example of error

Mixing the order arbitrarily.

public class BaseEntity { }
public interface ILoggable { }

// ⛔️ Error CS0401: 'new()' is in the middle.
// ⛔️ Also potentially CS0449 (Base class must come first).
public class Repository<T> where T : ILoggable, new(), BaseEntity
{
}

Solution

Follow the hierarchy: Base Class -> Interfaces -> new().

public class BaseEntity { }
public interface ILoggable { }

// ✅ Correct Order:
// 1. Base Class (BaseEntity)
// 2. Interface (ILoggable)
// 3. Constructor (new())
public class Repository<T> where T : BaseEntity, ILoggable, new()
{
public T CreateInstance()
{
return new T();
}
}
note

If you are using the class or struct constraint (instead of a specific Base Class name), those must also come first. Ex: where T : class, ILoggable, new()

Conclusion

CS0401 is a simple formatting rule enforced by the compiler to keep generic definitions consistent.

  1. Identify the where clause: Look for the generic type definition.
  2. Find new(): Locate the constructor constraint.
  3. Move it: Cut and paste new() so it is the absolutely last item in that comma-separated list.