How it works
A generic method or class works with a type parameter instead of one fixed concrete type. Without constraints, the implementation knows very little about that type. Constraints add a contract: the type may need to implement an interface, inherit from a base class, be a reference or value type, or provide a public parameterless constructor.
The new() constraint is useful when generic code genuinely needs to construct an instance. An interface constraint can then describe what the new instance must be able to do. This combination allows the compiler to check the generic implementation and every call site. It is more precise than constructing arbitrary objects through reflection and discovering missing capabilities only at runtime.
Walk through the example. CreateNamed requires a reference type implementing INamed with a public parameterless constructor. The method creates a T and assigns its Name through the interface contract. Label satisfies those constraints and receives the supplied name. A second call produces another independent instance, so changing its name does not replace or mutate the first label.
Watch the boundary. A parameterless constructor constraint guarantees only that construction is syntactically available. It does not prove that the resulting object's business state is useful or valid for every operation. If construction needs essential dependencies, accepting a factory delegate can be clearer than forcing a parameterless constructor onto the type. Constraints should express real requirements rather than dictate an awkward model merely to satisfy generic code.
Practice independently. Create a generic initializer for objects that implement a small resettable interface. Decide whether the method should construct the object or receive one from the caller. Add a type that lacks a public parameterless constructor and explain the resulting compile-time restriction. Then replace construction with a Func<T> factory and compare how required constructor dependencies can be supplied without weakening the object's invariants.
A working example
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
T CreateNamed<T>(string name) where T : class, INamed, new()
{
var item = new T();
item.Name = name;
return item;
}
var first = CreateNamed<Label>("first");
var second = CreateNamed<Label>("second");
Console.WriteLine(first.Name);
Console.WriteLine(second.Name);
Console.WriteLine(ReferenceEquals(first, second));
interface INamed { string Name { get; set; } }
sealed class Label : INamed { public string Name { get; set; } = ""; }
Expected output
first second False
Constraints make required capabilities explicit; use a factory when construction needs real dependencies.