具有设置支持字段的必需 init 属性仍然会给出空警告。
下面的代码给出了一个警告:
警告 CS8618 退出构造函数时,不可空字段“_name”必须包含非空值。考虑将该字段声明为可为空。
public class TestRequiredInit
{
private readonly string _name;
public required string Name
{
get => _name;
init => _name = value;
}
}
Run Code Online (Sandbox Code Playgroud)
我没有看到一种TestRequiredInit在不_name设置为非空值的情况下创建的方法。

这是 MSBuild / VS 中的错误,还是我遗漏了什么?
为了提出问题,我对上面的代码进行了一些简化。我希望能够向属性初始值设定项添加初始化逻辑。
public class TestRequiredInit
{
private readonly string _name;
public required string Name
{
get => _name;
init
{
if (value.Length > 50)
{
throw new ArgumentException();
}
_name = value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
属性与其支持字段之间没有正式的链接(如果它们有的话,这不是必需的),因此_name必须单独分析 的可为空性Name。更重要的是,虽然initsetter 被认为是作为构造阶段的一部分发生的(因此它们可以执行诸如初始化其他init属性之类的事情),但它们并不是出于可空性分析目的而正式构造的一部分 - 在引入 之前这是正确的required,因为没有要求给他们打电话。
可空性分析可以扩展到专门考虑属性init的 setterrequired作为分析目的的构造的一部分,因此Name initsetter 将被视为_name处于已知的非 null 状态,但是正确实现这一点并不简单 - 例如,因为我们不能假设init调用 setter 的任何顺序,我们应该假设在每个setter内部,如果构造函数没有明确将字段分配为非 null,则字段可能是这样,这样我们就可以给出适当的警告。这是当前语义的反转,其中允许 setter假设字段 not ,因为它们当前可以依赖已完成此操作的构造函数,并受到现有警告的限制。如果属性的 setter 不是 setter,事情会变得更加棘手,因为它可能在构造期间和之后被调用 - 我们是否应该始终发出警告以确保安全?initnullnullrequiredinit
所有这些,我什至没有考虑它如何与派生类交互。我肯定会同意“这可能被认为是一个错误,但正式定义所需的语义并尽可能少地实现它们是一项相当大的工作,但尚未进行”。
| 归档时间: |
|
| 查看次数: |
716 次 |
| 最近记录: |