Type constraints
Learn to constrain types with where clauses for class, struct and new().
Type constraints with where
Sometimes you want to restrict what a generic type parameter can be. The where clause does this. The line class Factory<T> where T : new() says T must have a parameterless constructor.
Other constraints: where T : class (reference type), where T : struct (value type), where T : IComparable<T> (a specific interface). With a constraint in place, the compiler lets you use what the constraint guarantees. For example, with new() you can write new T().
Creating instances with the new() constraint
The new() constraint lets you write new T() inside a generic class to create a fresh T instance. This is handy for implementing a factory pattern.
Example: class Factory<T> where T : new() { public T Create() { return new T(); } }. This class produces new instances of any type that has a parameterless constructor. Without the constraint you could not write new T(); the compiler would not know whether T has a constructor.
Exercise Create instances with Factory<T>
Define a Factory<T> generic class with the where T : new() constraint. Inside, a public T Create() method does return new T();. Define a Widget class with public string Name { get; set; } = "Hello";. In Main create a Factory<Widget> instance, call Create and print Name.
Show example solution
Write class Factory<T> where T : new() { public T Create() { return new T(); } }. In Main add var f = new Factory<Widget>(); var w = f.Create(); Console.WriteLine(w.Name);
Example solution:
using System;
class Factory<T> where T : new()
{
public T Create()
{
return new T();
}
}
class Widget
{
public string Name { get; set; } = "Hello";
}
class Program
{
static void Main()
{
var f = new Factory<Widget>();
var w = f.Create();
Console.WriteLine(w.Name);
}
}
Test yourself
-
Match each constraint to its meaning
- where T : class
- Reference type
- where T : struct
- Value type
- where T : new()
- Parameterless ctor
- where T : IComparable<T>
- Comparable
-
The constraint clause
class Factory<T> ____ T : new() { }Show answer
class Factory<T> where T : new() { } -
What does the new() constraint enable?
class Factory<T> where T : new() { public T Create() => ...; }- T must be a reference type
- T must be a value type
- Writing new T() inside
- T must be sealed
Show answer
Writing new T() inside — Correct. The new() constraint allows writing new T().