有什么方法可以通过某些 属性 来使可空引用推断为非空,以确保它不是?

Any way to make nullable references deduce being non-null via some property that ensures that it is not?

假设我们有这个 MCVE

class Person
{
    public int? Age;
    public string? Name;

    public bool IsInvalid => Name == null || Age == null;

    // ...

    public void Something(Person other) 
    {
        if (other.IsInvalid)
            return;

        Console.WriteLine(other.Name);
        Console.WriteLine(other.Age);
    }
}

这会向我抱怨,因为编译器宁愿在 if 语句中包含 属性 的表达式。

在我的实际代码中,我有这样的条件,但 属性 使其比检查一系列空值更具可读性。是否有一些属性或我可以做的事情让编译器意识到 属性 给我非空值?

我也完全理解,这对于编译器来说可能是一项非常重要的任务,因此现在可能无法实现。

这也是通过 .NET Core 3.0 Preview 9 完成的,因此在撰写本文时,我可以访问所有可能存在的属性。

首先,年龄和姓名是字段,不是属性。这很重要,因为这意味着不能使用仅适用于属性的属性,例如 NotNullIfNotNull

在任何情况下,属性用于指定特定代码(方法、getter、setter 等)的前置条件和 post 条件,而不是对象不变量。没有属性可以将一个 属性 的可空性与另一个的值联系起来。

另一方面,NotNullWhen 可用于将方法的参数与其 return 值联系起来,例如:

public bool GetValidValues([NotNullWhen(true)]out int? age, [NotNullWhen(true)]out string? name)
{
    age=Age;
    name=Name;
    return !IsInvalid;
}

使用 GetValidValues 不会生成任何可空性警告;

public void Something(Person other) 
{
    if (!other.GetValidValues(out var age,out var name))
        return;

    Console.WriteLine(name.Length);
    Console.WriteLine(age);
}