[英]Constraints on type parameters - new()
根据MSDN , new()
约束用于确保类型参数必须具有公共无参数构造函数。 但是,请考虑下面给出的示例(取自同一页面)。
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()
{
}
在这里, Employee
类型没有无参数/默认构造函数,但此代码编译成功。 有人可以详细说明这个约束的用法以及为什么会这样吗?
代码可以编译,因为完全有可能使用无参数构造函数从Employee
派生类型 - 这就是约束所说的。 约束并不是说Employee
本身有一个无参数的构造函数,实际上使用EmployeeList<Employee>
的尝试会因为约束不满足而失败。
作为有效的示例:
public class GeneratedEmployee : Employee
{
public GeneratedEmployee() : base(GenerateName(), GenerateId())
{
}
private static string GenerateName()
{
// Implementation here
}
private static int GenerateId()
{
// Implementation here
}
}
此时,可以创建一个EmployeeList<GeneratedEmployee>
,并假设EmployeeList<>
class 在实现中的某处使用new()
,它将调用GeneratedEmployee
的无参数构造函数。
也就是说,这是一个非常奇怪的约束,因为我不希望您真的想在不指定名称和 ID 的情况下创建员工。
class EmployeeList<T> where T : Employee, new()
{
}
T
必须是具有无参数构造函数的Employee
的Employee
后代,但Employee
没有这一事实并不意味着它的后代不能拥有它。
即new()
约束将阻止new EmployeeList<Employee>();
从编译,但你可以这样做:
class EmployeeChild : Employee
{
public EmployeeChild() : base("", 1)
{
}
}
这将满足所有约束和new EmployeeList<EmployeeChild>();
会编译得很好。
您的列表显示 class 必须是 Employee 或派生自 Employee。 Employee 本身没有无参数构造函数,因此它会作为类型参数失败:
//fails to compile
var xx = new EmployeeList<Employee>()
但是,如果您定义了一个继承自 Employee 的 class:
public class EmployeeDerived : Employee
{
public EmployeeDerived() : base("test", 123)
{
}
}
这个 class 确实有一个无参数的构造函数(尽管它非常没用)。 因此编译器可以将其用作 EmployeeList 的T
即使Employee
没有无参数构造函数, Employee
的子类也可以!
public class Manager: Employee {
// these parameters don't make sense - just an example
public EmployeeSubclass(): base("foo", 1) {
}
}
然后我可以使用Manager
作为EmployeeList
- EmployeeList<Manager>
的类型参数。 它满足两个约束!
在这里,Employee 类型没有无参数/默认构造函数,但此代码编译成功
没错,但是您没有尝试过的是实际使用 class。 没有编译的是实际上试图调用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>'
正如您正确引用的那样, Employee
与约束T: Employee, new()
不匹配。 给它匹配的东西的唯一方法是从Employee
派生一个 class ,它确实实现了默认构造函数,并提供它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.