[英]Constraints on type parameters - new()
As per MSDN , the new()
constraint is used to ensure that the type argument must have a public parameterless constructor .根据MSDN ,
new()
约束用于确保类型参数必须具有公共无参数构造函数。 However, consider the example given below (taken from the same page).但是,请考虑下面给出的示例(取自同一页面)。
public class Employee
{
public Employee(string name, int id)
{
Name = name;
ID = id;
}
public string Name { get; set; }
public int ID { get; set; }
}
class EmployeeList<T> where T : Employee, new()
{
}
Here, the Employee
type does not have a parameterless/default constructor, yet this code compiles successfully.在这里,
Employee
类型没有无参数/默认构造函数,但此代码编译成功。 Can someone please elaborate on the usage of this constraint and why this works?有人可以详细说明这个约束的用法以及为什么会这样吗?
The code compiles because it's entirely possible to have a type derived from Employee
with a parameterless constructor - and that's what the constraint says.代码可以编译,因为完全有可能使用无参数构造函数从
Employee
派生类型 - 这就是约束所说的。 The constraint is not trying to say that Employee
itself has a parameterless constructor, and indeed an attempt to use EmployeeList<Employee>
would fail as the constraint isn't satisfied.约束并不是说
Employee
本身有一个无参数的构造函数,实际上使用EmployeeList<Employee>
的尝试会因为约束不满足而失败。
As example of what would be valid:作为有效的示例:
public class GeneratedEmployee : Employee
{
public GeneratedEmployee() : base(GenerateName(), GenerateId())
{
}
private static string GenerateName()
{
// Implementation here
}
private static int GenerateId()
{
// Implementation here
}
}
At that point, it's fine to create an EmployeeList<GeneratedEmployee>
, and assuming the EmployeeList<>
class uses new()
somewhere in the implementation, it would call the parameterless constructor of GeneratedEmployee
.此时,可以创建一个
EmployeeList<GeneratedEmployee>
,并假设EmployeeList<>
class 在实现中的某处使用new()
,它将调用GeneratedEmployee
的无参数构造函数。
That said, it's a pretty odd constraint, as I wouldn't expect you to really want to create an employee without specifying the name and ID.也就是说,这是一个非常奇怪的约束,因为我不希望您真的想在不指定名称和 ID 的情况下创建员工。
class EmployeeList<T> where T : Employee, new()
{
}
T
must be Employee
descendant of Employee
with parameterless constructor but the fact that Employee
does not have one does not mean that it's descendants can't have it. T
必须是具有无参数构造函数的Employee
的Employee
后代,但Employee
没有这一事实并不意味着它的后代不能拥有它。
ie new()
constraint will prevent new EmployeeList<Employee>();
即
new()
约束将阻止new EmployeeList<Employee>();
from compiling, but you can do:从编译,但你可以这样做:
class EmployeeChild : Employee
{
public EmployeeChild() : base("", 1)
{
}
}
Which will satisfy all constraints and new EmployeeList<EmployeeChild>();
这将满足所有约束和
new EmployeeList<EmployeeChild>();
will compile just fine.会编译得很好。
Your list says that the class must be an Employee, or derived from Employee.您的列表显示 class 必须是 Employee 或派生自 Employee。 Employee itself does not have a parameterless constructor, so it would fail as the type argument:
Employee 本身没有无参数构造函数,因此它会作为类型参数失败:
//fails to compile
var xx = new EmployeeList<Employee>()
But, if you defined a class that inherited from Employee:但是,如果您定义了一个继承自 Employee 的 class:
public class EmployeeDerived : Employee
{
public EmployeeDerived() : base("test", 123)
{
}
}
This class does have a parameterless constructor (though it's pretty useless).这个 class 确实有一个无参数的构造函数(尽管它非常没用)。 So the compiler can use it as the
T
to EmployeeList因此编译器可以将其用作 EmployeeList 的
T
Even though Employee
doesn't have a parameterless constructor, a subclass of Employee
can !即使
Employee
没有无参数构造函数, Employee
的子类也可以!
public class Manager: Employee {
// these parameters don't make sense - just an example
public EmployeeSubclass(): base("foo", 1) {
}
}
Then I can use Manager
as the type argument for EmployeeList
- EmployeeList<Manager>
.然后我可以使用
Manager
作为EmployeeList
- EmployeeList<Manager>
的类型参数。 It satisfies both constraints!它满足两个约束!
Here, the Employee type does not have a parameterless/default constructor, yet this code compiles successfully
在这里,Employee 类型没有无参数/默认构造函数,但此代码编译成功
That's correct, however what you haven't tried is to actually use the class.没错,但是您没有尝试过的是实际使用 class。 What doesn't compile is actually trying to call
EmployeeList<Employee>
:没有编译的是实际上试图调用
EmployeeList<Employee>
:
CS0310 'Employee' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'EmployeeList<T>'
As you correctly quote, Employee
doesn't match the constraint T: Employee, new()
.正如您正确引用的那样,
Employee
与约束T: Employee, new()
不匹配。 The only way to give it something that will match it is to derive a class from Employee
that does implement a default constructor, and provide that.给它匹配的东西的唯一方法是从
Employee
派生一个 class ,它确实实现了默认构造函数,并提供它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.