What does "where T : class, new()" mean?

C#GenericsType Constraints

C# Problem Overview


Can you please explain to me what where T : class, new() means in the following line of code?

void Add<T>(T item) where T : class, new();

C# Solutions


Solution 1 - C#

That is a constraint on the generic parameter T. It must be a class (reference type) and must have a public parameter-less 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.

Solution 2 - C#

Those are generic type constraints. In your case there are two of them:

where T : class

Means that the type T must be a reference type (not a value type).

where T : 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.

You then combine the two using a comma to get:

where T : class, new()

Solution 3 - C#

where T : struct

The type argument must be a value type. Any value type except Nullable can be specified. See Using Nullable Types (C# Programming Guide) for more information.

where T : class

The type argument must be a reference type, including any class, interface, delegate, or array type. (See note below.)

where T : new() The type argument must have a public parameterless constructor. When used in conjunction with other constraints, the new() constraint must be specified last.

where T : [base class name]

The type argument must be or derive from the specified base class.

where T : [interface name]

The type argument must be or implement the specified interface. Multiple interface constraints can be specified. The constraining interface can also be generic.

where T : U

The type argument supplied for T must be or derive from the argument supplied for U. This is called a naked type constraint.

Solution 4 - C#

class & new are 2 constraints on the generic type parameter T.
Respectively they ensure:

class

> The type argument must be a reference type; this applies also to any class, interface, delegate, or array type.

new

> The type argument must have a public parameterless constructor. When used together with other constraints, the new() constraint must be specified last.

Their combination means that the type T must be a Reference Type (can't be a Value Type), and must have a parameterless constructor.

Example:

struct MyStruct { } // structs are value types

class MyClass1 { } // no constructors defined, so the class implicitly has a parameterless one

class MyClass2 // parameterless constructor explicitly defined
{
    public MyClass2() { }
}

class MyClass3 // only non-parameterless constructor defined
{
    public MyClass3(object parameter) { }
}

class MyClass4 // both parameterless & non-parameterless 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 parameterless ctor
    INewable<string> n2; // NOT ALLOWED: no parameterless ctor
    INewable<MyStruct> n3; // ALLOWED: has parameterless ctor
    INewable<MyClass1> n4; // ALLOWED: has parameterless ctor
    INewable<MyClass2> n5; // ALLOWED: has parameterless ctor
    INewable<MyClass3> n6; // NOT ALLOWED: no parameterless ctor
    INewable<MyClass4> n7; // ALLOWED: has parameterless ctor

    INewableReference<int> nr1; // NOT ALLOWED: not a reference type
    INewableReference<string> nr2; // NOT ALLOWED: no parameterless ctor
    INewableReference<MyStruct> nr3; // NOT ALLOWED: not a reference type
    INewableReference<MyClass1> nr4; // ALLOWED: has parameterless ctor
    INewableReference<MyClass2> nr5; // ALLOWED: has parameterless ctor
    INewableReference<MyClass3> nr6; // NOT ALLOWED: no parameterless ctor
    INewableReference<MyClass4> nr7; // ALLOWED: has parameterless ctor
}

Solution 5 - C#

new(): Specifying the new() constraint means type T must use a parameterless constructor, so an object can be instantiated from it - see Default constructors.

class: Means T must be a reference type so it can't be an int, float, double, DateTime or other struct (value type).

public void MakeCars()
{
	//This won't compile as researchEngine doesn't have a public constructor and so can't be instantiated.
	CarFactory<ResearchEngine> researchLine = new CarFactory<ResearchEngine>();
	var researchEngine = researchLine.MakeEngine();

	//Can instantiate new object of class with default public constructor
	CarFactory<ProductionEngine> productionLine = new CarFactory<ProductionEngine>();
	var productionEngine = productionLine.MakeEngine();
}

public class ProductionEngine { }
public class ResearchEngine
{
	private ResearchEngine() { }
}

public class CarFactory<TEngine> where TEngine : class, new()
{
	public TEngine MakeEngine()
	{
		return new TEngine();
	}
}

Solution 6 - C#

That means that type T must be a class and have a constructor that does not take any arguments.

For example, you must be able to do this:

T t = new T();

Solution 7 - C#

where (C# Reference)

>The new() Constraint lets the compiler know that any type argument supplied must have an accessible parameterless--or default-- constructor

So it should be, T must be a class, and have an accessible parameterless--or default constructor.

Solution 8 - C#

What comes after the "Where" is a constraint on the generic type T you declared, so:

  • class means that the T should be a class and not a value type or a struct.

  • new() indicates that the T class should have a public parameter-free default constructor defined.

Solution 9 - C#

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.

Solution 10 - C#

This is part of the Generics mechanism, where the where keyword add constraints to what types must implement in order to be used as type parameters.

Solution 11 - C#

when using the class in constraints it's mean you can only use Reference type, another thing to add is when to use the constraint new(), it's must be the last thing you write in the Constraints terms.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRawhi View Question on Stackoverflow
Solution 1 - C#NerdFuryView Answer on Stackoverflow
Solution 2 - C#Justin NiessnerView Answer on Stackoverflow
Solution 3 - C#Mohammed JubayerView Answer on Stackoverflow
Solution 4 - C#SergioView Answer on Stackoverflow
Solution 5 - C#BrendanView Answer on Stackoverflow
Solution 6 - C#Evan MulawskiView Answer on Stackoverflow
Solution 7 - C#Fredrik WiderbergView Answer on Stackoverflow
Solution 8 - C#Otman IGHOULASSENView Answer on Stackoverflow
Solution 9 - C#user197015View Answer on Stackoverflow
Solution 10 - C#Peter LillevoldView Answer on Stackoverflow
Solution 11 - C#RebwarView Answer on Stackoverflow