繁体   English   中英

类型参数的约束 - new()

[英]Constraints on type parameters - new()

根据MSDNnew()约束用于确保类型参数必须具有公共无参数构造函数 但是,请考虑下面给出的示例(取自同一页面)。

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必须是具有无参数构造函数的EmployeeEmployee后代,但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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM