【问题标题】:Is this the limitation of C# nullable checking? [duplicate]这是 C# 可空检查的限制吗? [复制]
【发布时间】:2020-12-18 01:30:15
【问题描述】:

我在引用 x 时收到了以下 CS8629 警告。由于select 之前的where 子句,我确信x.Value 永远不会是可为空的引用。这是 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);

【问题讨论】:

标签: c# nullable


【解决方案1】:

是的,这是极限。 LINQ 尚未使用可为空的注释进行注释。请参阅this answerthis issuethis 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();

【讨论】:

  • @AlexeiLevenkov 这个灵感来自 Java 的 Optional.stream 方法,与 flatMap 一起使用 :) Haskell 中也有 maybeToList。这并不是真的不常见。
  • 为每个元素创建一个新的状态机有点昂贵。为什么不一口气过滤和选择WhereHasValue&lt;T&gt;(this IEnumerable&lt;Nullable&lt;T&gt;&gt; t)) ...
  • @JeremyLakeman 是的,我想这是真的。我只是希望它尽可能简洁。 (我很懒 :D)使用Enumerable.RepeatEnumerable.Empty 怎么样?
【解决方案2】:

虽然不会返回 null,但请尝试将 MyEnum? 转换为 MyEnum

像这样:

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

【讨论】:

    猜你喜欢
    • 2019-06-11
    • 2011-06-27
    • 2019-12-01
    • 1970-01-01
    • 2018-11-13
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多