Introduction
Generic constraints help you tell the computer what kind of data a generic type can work with. This keeps your code safe and clear.
class ClassName<T> where T : constraint1, constraint2 { // class body } // Example constraints: struct, class, new(), base class, interface
where clause sets rules for the generic type T.class DataStore<T> where T : class { // T must be a reference type }
class NumberHolder<T> where T : struct { // T must be a value type like int or double }
class Factory<T> where T : new() { public T Create() => new T(); }
class ComparableList<T> where T : IComparable<T> { // T must implement IComparable<T> }
where T : new() means T must have a parameterless constructor. We create a Product object and print its Name.using System; class Factory<T> where T : new() { public T Create() => new T(); } class Product { public string Name = "Sample Product"; } class Program { static void Main() { var factory = new Factory<Product>(); Product p = factory.Create(); Console.WriteLine(p.Name); } }
where constraints to restrict to specific values, only types or features.new() constraint must come last if combined with others.where clause to set these rules clearly.where clause in C# generic constraints?where clause restricts which types can be used with a generic type parameter.where clausewhere as a filter for allowed types [OK]where with method return typeswhere defines new typeswhere for database queriesT to be a class in C#?class means the type must be a reference type (class).where T : class correctly restricts T to reference types.class keyword [OK]class means reference type, struct means value type [OK]struct to mean classnew() with class constraintinterface as a constraint keywordclass Repository<T> where T : IEntity { public void Save(T item) { item.Save(); } }
interface IEntity { void Save(); }Repository<string>?TT must implement IEntity.string implements IEntitystring does not implement IEntity, so it violates the constraint.class DataManager<T> where T : new, class { }class or struct constraints must come before new().new before class, which is invalid.class must come before new() -> Option Bclass or struct first, then new() [OK]new() before classnew()IDisposable, and have a parameterless constructor. Which is the correct declaration?class must come first, then interfaces, then new().class, IDisposable, new().new() before classPass the test and this pattern moves unknown