这是 C# 可空检查的局限性吗?

Is this the limitation of C# nullable checking?

我在引用 x 时收到了以下 CS8629 警告。由于 select 之前的 where 子句,我确信 x.Value 永远不会是可为 null 的引用。这是 C# 空检查的内在限制吗?除了抑制 CS8629 警告之外,还有什么方法可以消除它吗?

var myEnums = myStrings
      .Select(x => x.ToEnum<MyEnum>())
      .Where(x => x.HasValue)
      .Select(x => x.Value)  //CS8629 on x.
      .ToList();
MyEnum? ToEnum(this string str);

虽然没有 null return,但请尝试将 MyEnum? 转换为 MyEnum

像这样:

MyEnum myEnums = myStrings
      .Select(x => x.ToEnum<MyEnum>())
      .Where(x => x.HasValue)
      .Select(x => x.Value)  //CS8629 on x.
      .ToList();

是的,这是极限。 LINQ 尚未使用可空注释进行注释。见, this issue and this issue,全部开放

如果实在不想用!,可以这样写:

static IEnumerable<T> AsEnumerable<T>(this Nullable<T> t) where T : struct {
    if (t.HasValue) {
        return Enumerable.Repeat(t.Value, 1);
    }
    return Enumerable.Empty<T>();
}

然后使用SelectMany:

var myEnums = myStrings
      .Select(x => x.ToEnum())
      .SelectMany(x => x.AsEnumerable())
      .ToList();