当某个方法已执行时,如何告诉编译器属性不为 null?

How do I tell the compiler that a property is not null when a certain method has been executed?

提问人:Marvin Klein 提问时间:6/26/2023 更新时间:6/26/2023 访问量:137

问:

在我的基类中考虑这段代码

public MyClass? Input { get; set; }
protected virtual void DoSomething()
{
    Input = new();
}

现在,我想重写该方法并修改 Input 属性上的一些属性。

protected override void DoSomething()
{
    base.DoSomething();

    Input.Name = "Test";
}

现在我收到警告

CS8602 - Dereference of a possibly null reference.

我知道我可以说,这样做不能为零:

Input!.Name = "Test";

但我不想每次都这样做。当函数的基已经执行时,有没有更好的方法可以告诉编译器 Input 不为 null?

C# 可为 null

评论

1赞 Zohar Peled 6/26/2023
旁注:考虑到该属性具有公共集这一事实,如果您在多线程环境中工作,即使您在调用 base 后立即使用它,您甚至无法确定它不会为 null,而无需实现锁定机制。Input
0赞 canton7 6/26/2023
@ZoharPeled 在许多情况下,如果有多个线程同时操作成员,则 NRT 给出的警告无效。对此提供警告显然不是NRT的目标。
0赞 Marvin Klein 6/26/2023
感谢您的输入。就我而言,我没有使用多线程环境,因此下面的两个 anser 正是我正在寻找的。

答:

4赞 canton7 6/26/2023 #1

您需要 [MemberNotNull(nameof(Input))]

这会告知编译器,在修饰方法执行后,命名属性将为非 null。

[MemberNotNull(nameof(Input))]
protected virtual void DoSomething()
{
    Input = new();
}

夏普实验室

4赞 jraufeisen 6/26/2023 #2

为此,可以使用 MemberNotNull

[MemberNotNull(nameof(Input)]
protected virtual void DoSomething()
{
    Input = new();
}