您能否向我解释一下以下代码行中的 where T : class, new()
是什么意思?
void Add<T>(T item) where T : class, new();
这是对泛型参数 T
的约束。它必须是 class
(引用类型)并且必须具有公共无参数默认构造函数。
这意味着 T
不能是 int
、float
、double
、DateTime
或任何其他 struct
(值类型)。
它可以是 string
或任何其他自定义引用类型,只要它具有默认或无参数构造函数即可。
这些是通用类型约束。在您的情况下,有两个:
where T : class
表示类型 T
必须是引用类型(不是值类型)。
where T : new()
表示类型 T
必须具有无参数构造函数。拥有此约束将允许您在代码中执行类似 T field = new T();
的操作,否则您将无法执行此操作。
然后,您使用逗号将两者结合以获得:
where T : class, new()
其中 T : 结构
类型参数必须是值类型。可以指定除 Nullable 之外的任何值类型。有关更多信息,请参阅使用 Nullable 类型(C# 编程指南)。
其中 T :类
类型参数必须是引用类型,包括任何类、接口、委托或数组类型。 (见下面的注释。)
其中 T : new() 类型参数必须具有公共无参数构造函数。当与其他约束结合使用时,必须最后指定 new() 约束。
其中 T : [基类名称]
类型参数必须是或派生自指定的基类。
其中 T : [接口名称]
类型参数必须是或实现指定的接口。可以指定多个接口约束。约束接口也可以是通用的。
其中 T : U
为 T 提供的类型参数必须是或派生自为 U 提供的参数。这称为裸类型约束。
class
& new
是 2 个 constraints on the generic type parameter T
。
它们分别确保:
班级
类型参数必须是引用类型;这也适用于任何类、接口、委托或数组类型。
新的
类型参数必须有一个公共的无参数构造函数。当与其他约束一起使用时,必须最后指定 new() 约束。
它们的组合意味着类型 T
必须是 Reference Type(不能是 Value Type),并且必须具有无参数构造函数。
例子:
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
}
new(): 指定 new() 约束意味着类型 T 必须使用无参数构造函数,因此可以从中实例化对象 - 参见 Default constructors。
class:表示 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();
}
}
这意味着类型 T
必须是一个类并且有一个不带任何参数的构造函数。
例如,您必须能够这样做:
T t = new T();
new() 约束让编译器知道提供的任何类型参数都必须具有可访问的无参数(或默认)构造函数
所以它应该是,T
必须是一个类,并且有一个可访问的无参数 - 或默认构造函数。
“Where”之后是对您声明的泛型类型 T 的约束,因此:
class 意味着 T 应该是一个类而不是值类型或结构。
new() 表示 T 类应该定义一个公共的无参数默认构造函数。
它在泛型参数 T 上称为“约束”。这意味着 T 必须是引用类型(类)并且它必须具有公共默认构造函数。
这是泛型机制的一部分,其中 where 关键字将约束添加到必须实现的类型才能用作类型参数。
当在约束中使用类时,这意味着您只能使用引用类型,要添加的另一件事是何时使用约束 new(),它必须是您在约束条款中写的最后一件事。
new()
精确指定“必须有一个公共无参数构造函数”