如何避免不相关的可空警告(没有明确禁止)

How to avoid irrelevant nullable warning (without explicit suppression)

有没有办法让分析器理解变量 Bar 对以下情况有值?

#nullable enable 
class Foo {
   bool GenerateArray => Bar.HasValue;
   int? Bar { get; set; }
   void FooBar() {
     var data = (GenerateArray) ? new int[Bar.Value] : null;
   }
}

出现警告“可为空的值类型可能为空”。对于 Bar.Value 但显然不可能。

我知道有两种避免警告的方法。两者都有缺点:

  1. 直接使用 Bar.HasValue 而不是 属性 GenerateArray。但是使用 GenerateArray 提高了可读性。
  2. 使用 Bar!.Value 而不是 Bar.Value。但是,如果有人更改了代码,例如,在将来将 GenerateArray 设置为自动 属性,警告可能会再次变得相关,但不会出现。

此处的问题与 略有不同,后者使用局部变量而不是 属性。如果我理解正确,下面接受的答案适用于 属性 但不适用于局部变量(一旦 C# 9 发布)。因此,问题不是重复的。

在 mahesh_b 的评论中的 link 之后,我发现 this roslyn issues 指出,遗憾的是,没有其他方法可以避免 C# 8.0 中的警告。

将能够在 C# 9 中使用 MemberNotNullWhen 属性(目前处于预览阶段):

[MemberNotNullWhen(true, "Bar")]
bool GenerateArray => Bar.HasValue;

.Net 5 中将存在相关属性类型:

namespace System.Diagnostics.CodeAnalysis
{
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
    public sealed class MemberNotNullAttribute : Attribute
    {
        public MemberNotNullAttribute(params string[] members) { }
        public MemberNotNullAttribute(string member) { }
    }
}

namespace System.Diagnostics.CodeAnalysis
{
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
    public sealed class MemberNotNullWhenAttribute : Attribute
    {
        public MemberNotNullWhenAttribute(bool when, params string[] members) { }
        public MemberNotNullWhenAttribute(bool when, string member) { }
    }
}

Illustration on sharplab