Let’s start with a piece of code;
void Add<T>(T item) where T : class, new();
It’s called a ‘constraint’ on the generic parameter T. It means that T must be a reference type (a class) and that it must have a public default constructor.
That means T can’t be an int, float, double, DateTime or any other struct (value type). It could be a string, or any other custom reference type, as long as it has a default or parameter-less constructor.
For understanding we can break it into two parts;
whereT :
class
Means that the type T
must be a reference type (not a value type).
whereT :
new()
Means that the type T
must have a parameter-less constructor. Having this constraint will allow you to do something like T field = new T();
in your code which you wouldn’t be able to do otherwise.
We then combine the two using a comma to get:
whereT :
class,
new()
Just to clarify, if you don’t have the class clause as part of the where T…, then it is safe to use int, float, double etc
Here is an example;
struct MyStruct { } // structs are value types
class MyClass1 { } // no constructors defined, so the class implicitly has a parameter less one
class MyClass2 // parameter less constructor explicitly defined
{
public MyClass2() { }
}
class MyClass3 // only non-parameter less constructor defined
{
public MyClass3(object parameter) { }
}
class MyClass4 // both parameter less & non-parameter less constructors defined
{
public MyClass4() { }
public MyClass4(object parameter) { }
}
interface INewable<T>
where T : new()
{
}
interface INewableReference<T>
where T : class, new()
{
}
class Checks
{
INewable<int> cn1; // ALLOWED: has parameter less ctor
INewable<string> n2; // NOT ALLOWED: no parameter less ctor
INewable<MyStruct> n3; // ALLOWED: has parameter less ctor
INewable<MyClass1> n4; // ALLOWED: has parameter less ctor
INewable<MyClass2> n5; // ALLOWED: has parameter less ctor
INewable<MyClass3> n6; // NOT ALLOWED: no parameter less ctor
INewable<MyClass4> n7; // ALLOWED: has parameter less ctor
INewableReference<int> nr1; // NOT ALLOWED: not a reference type
INewableReference<string> nr2; // NOT ALLOWED: no parameter less ctor
INewableReference<MyStruct> nr3; // NOT ALLOWED: not a reference type
INewableReference<MyClass1> nr4; // ALLOWED: has parameter less ctor
INewableReference<MyClass2> nr5; // ALLOWED: has parameter less ctor
INewableReference<MyClass3> nr6; // NOT ALLOWED: no parameter less ctor
INewableReference<MyClass4> nr7; // ALLOWED: has parameter less ctor
}
Resources
https://stackoverflow.com/questions/4737970/what-does-where-t-class-new-mean