【问题标题】:C# result type of list after removing nulls from a list of optionals从可选列表中删除空值后列表的 C# 结果类型
【发布时间】:2016-09-20 07:22:00
【问题描述】:

假设我有一个 C# 选项列表(这里称为 x),我通过删除空值创建一个新列表(这里新列表称为 y

static void Main()
{
    var x = new List<long?> { 7, 8, 9, null, 10, null, 11 };
    var y = x.Where(e => e != null);
    Console.WriteLine("{0}", y);
}

那么y的类型被推断为List&lt;long?&gt;。获得List&lt;long&gt; 类型的惯用方法是什么?显式展开或显式转换?还是有更清洁的方法?

在我正在处理的实际实现中,值作为可选列表进来,我需要将这些列表转换为下游的集合,因此“将责任推给后续操作”不是我想做的事情(尽管我可以稍后在代码中进行大量的空值检查......yuk)。我真的很想有一个长变量列表。在 C# 中如何最好地思考和处理这个问题?

【问题讨论】:

    标签: c# linq optional


    【解决方案1】:

    只需使用x.OfType&lt;long&gt;().ToList() - 这将过滤掉所有空值,结果类型将为List&lt;long&gt;

    【讨论】:

    • 虽然简明扼要,但 IMO 这对它所做的工作来说有点过头了,因为它涉及到不必要的装箱和拆箱。
    • @IvanStoev 这是一个非常有用的评论。很难在简明扼要地说“只保留所有长字”的答案和 Jeroen 的答案之间做出决定,后者非常明确地将展开的值放在它们存在的地方!
    • 您对拳击的看法是对的,但对于示例中的列表,我什至不会考虑。无论如何,您始终可以使用Where-&gt;Select 方法。
    【解决方案2】:

    我会检查HasValue 属性并选择Value

    你可以试试这个:

    var y = x.Where(e => e.HasValue).Select(e => e.Value);
    

    有或没有.ToList()

    【讨论】:

      【解决方案3】:

      我认为最好的方法是创建自己的扩展方法:

      public static class Extensions
      {
          public static IEnumerable<T> RemoveNullsAndConvert<T>(this IEnumerable<T?> source)
              where T : struct
          {
              return from x in source where x != null select x.Value;
          }
      }
      

      然后简单地使用

      var y = x.RemoveNullsAndConvert();
      

      当然,您可以为方法使用较短的名称,并且实现不一定必须使用 LINQ - 例如它可以是 C# 迭代器:

      public static class Extensions
      {
          public static IEnumerable<T> RemoveNullsAndConvert<T>(this IEnumerable<T?> source)
              where T : struct
          {
              foreach (var x in source)
                  if (x != null) yield return x.Value;
          }
      }
      

      【讨论】:

        【解决方案4】:

        使用 Select 进行显式转换就可以了:

                var x = new List<long?> { 7, 8, 9, null, 10, null, 11 };
                var y = x.Where(e => e != null);
                Console.WriteLine("{0}", y);
                IEnumerable<long> z = x.Where(e => e != null).Select(e => (long)e);
                Console.WriteLine("{0}", z);
        

        【讨论】:

          猜你喜欢
          • 2016-02-17
          • 2019-12-22
          • 2019-10-03
          • 1970-01-01
          • 2017-08-07
          • 1970-01-01
          • 2014-01-06
          • 2017-11-02
          • 2022-11-01
          相关资源
          最近更新 更多