where T: class, new();的意思吗?

你能解释一下下面这行代码中的where T : class, new()是什么意思吗?

void Add<T>(T item) where T : class, new();
156308 次浏览

这是对泛型参数T的约束。它必须是class(引用类型),并且必须有一个无公共参数的默认构造函数。

这意味着T不能是intfloatdoubleDateTime或任何其他struct(值类型)。

它可以是string,或任何其他自定义引用类型,只要它有默认或无参数构造函数。

这意味着类型T必须是一个类而且有一个不带任何参数的构造函数。

例如,你必须能够这样做:

T t = new T();

它被称为泛型参数T上的“约束”。这意味着T必须是一个引用类型(一个类),并且它必须有一个公共默认构造函数。

这是泛型机制的一部分,其中where关键字为必须实现的类型添加约束,以便用作类型参数。

where (c# Reference)

new() Constraint让编译器知道提供的任何类型参数必须有一个可访问的无参数——或默认——构造函数

所以它应该是,T必须是一个类,并且有一个可访问的无参数——或默认构造函数。

这些是泛型类型约束。在你的例子中有两个:

where T : class

意味着类型T必须是引用类型(而不是值类型)。

where T : new()

意思是类型T必须有一个无参数的构造函数。有了这个约束,你就可以在你的代码中做一些类似T field = new T();的事情,否则你就不能这样做。

然后用逗号将两者结合起来,得到:

where T : class, new()

where T: struct

type参数必须是值类型。可以指定除Nullable以外的任何值类型。更多信息请参见使用可空类型(c#编程指南)。

T:类

类型参数必须是引用类型,包括任何类、接口、委托或数组类型。(见下文附注)

where T: new() 类型参数必须有一个公共的无参数构造函数。当与其他约束一起使用时,new()约束必须在最后指定

其中T:[基类名]

类型参数必须是或派生自指定的基类。

其中T:[接口名]

类型参数必须是或实现指定的接口。可以指定多个接口约束。约束接口也可以是通用的。

其中T: U

为T提供的类型参数必须是为u提供的类型参数,或者派生自u的类型参数。这被称为裸类型约束。

(原始来源:https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters)

新():指定new()约束意味着类型T必须使用无参数构造函数,因此可以从它实例化对象-参见默认构造函数

类:表示T必须是引用类型,因此它不能是int、float、double、DateTime或其他结构(值类型)。

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();
}
}

“Where”后面的是对你声明的泛型类型T的约束,所以:

  • class意味着T应该是一个类,而不是值类型或结构体。

  • new()表示T类应该定义一个没有公共形参的默认构造函数。

< p > class,new是2 泛型类型参数T的约束.
它们分别确保:

class

type参数必须是引用类型;这也适用于任何类、接口、委托或数组类型。

new

类型参数必须有一个公共的无参数构造函数。当与其他约束一起使用时,new()约束必须在最后指定。

它们的组合意味着类型T必须是引用类型(不能是值类型),并且必须有一个无参数构造函数。

例子:

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
}

当在约束中使用时,这意味着你只能使用引用类型,另一件要添加的事情是当使用约束新()时,它必须是你在约束术语中写的最后一件事。