【问题标题】:Concat 2 lists when one is null当一个为空时,Concat 2 列出
【发布时间】:2014-01-31 21:53:24
【问题描述】:

当代码行下面的两个列表都被填充时,我的代码可以正常工作。 但是错误“值不能为空”。当 LstNewItems 设置为 null 时发生。 为什么以及如何解决这个问题,或者我是否必须事先检查每个列表是否为空并采取相应措施?

this.radGridViewFiles.BeginInvoke((MethodInvoker)(
() => this.radGridViewFiles.DataSource = MyGlobals.ListOfItemsToControl
                                                  .Concat(MyGlobals.lstNewItems)
                                                  .ToList()
));

【问题讨论】:

  • 如果可能的话,永远不要让自己处于列表为 null 的位置,这样您就不需要检查 null 并以任何不同的方式处理这种情况。拥有一个空列表而不是 null 几乎总是更可取的。
  • 检查并采取相应措施将有资格修复它 :-) 但是拥有 null 列表是 IMO 的轻微代码气味,也许它应该修复在那个级别。
  • @Servy 你是绝对正确的 - 我将列表设置为 null 我应该有 MyGlobals.lstNewItems.Clear() - 谢谢 - 你想把它作为答案吗?

标签: c# list concatenation


【解决方案1】:

当您有任意数量的可能为空的集合要连接时:

IEnumerable<T> Concat<T>(params IEnumerable<T>[] nullableCollections)
{
    return nullableCollections.Where(nc => nc != null).SelectMany(nc => nc);
}

稍后您可以致电:

IEnumerable<T> allElements = Concat(myElements, yourElements, theirElements);

不用担心它们是否为空。

【讨论】:

    【解决方案2】:

    我所做的是创建一个扩展方法,如果枚举为空,则可以创建一个空列表:

    public static IEnumerable<T> NeverNull<T>(this IEnumerable<T> value)
    {
       return value ?? Enumerable.Empty<T>();
    }
    

    那么你可以这样做:

    this.radGridViewFiles.BeginInvoke((MethodInvoker)(
    () => this.radGridViewFiles.DataSource = MyGlobals.ListOfItemsToControl
                                                      .Concat(MyGlobals.lstNewItems.NeverNull())
                                                      .ToList()
    ));
    

    Example

    【讨论】:

    • 这会像 OP 的代码一样抛出一个参数空异常。你在null上打电话给DefaultIfEmpty
    • @Servy - 错误。 DefaultIfEmpty 本身就是一个扩展方法,因此在 null 上调用它非常好。我在我的几个项目中使用了这段代码。
    • 我的错误,你会得到另一个参数空异常,而不是 NRE。所以这对 OP 的代码同样有问题。
    • @Servy - 完全搞砸了,我的意思是 Enumerable.Empty&lt;&gt; 不是 .DefaultIfEmpty。这就是我从记忆中写出来的结果,而不是花 30 秒来挖掘我的实际代码。
    【解决方案3】:

    如果可能的话,永远不要让自己处于列表为null 的位置,这样您就不需要检查null 并以不同的方式处理这种情况。拥有一个空列表而不是 null 几乎总是更可取的。

    【讨论】:

    • 我将列表设置为 null 我应该有 MyGlobals.lstNewItems.Clear()
    【解决方案4】:

    你可以使用

    MyGlobals.lstNewItems ?? Enumerable.Empty<someObjectType>()
    

    【讨论】:

    • 如果它是匿名类型的列表 ;)
    • 你能更具体地说明我需要的代码行吗?
    【解决方案5】:

    试试这个

     ( MyGlobals.ListOfItemsToControl ?? new List<Type>()).Concat(MyGlobals.lstNewItems ?? new List<Type>()) .ToList()
    

    【讨论】:

    • 运算符'??'不能应用于“System.Collections.Generic.List”和“System.Collections.Generic.List”类型的操作数
    • 这里 Type 将是您的项目的类型。例如,如果它是字符串而不是您应该写的 (MyGlobals.ListOfItemsToControl ?? new List()) .Concat(MyGlobals.lstNewItems ??新列表()) .ToList()
    • 在你的情况下类型是 ValidState.ItemsUnderControlObject 那么你应该使用 (MyGlobals.ListOfItemsToControl ?? new List()) .Concat(MyGlobals.lstNewItems ?? new List()) .ToList()
    【解决方案6】:

    在连接之前检查 null。喜欢,

    if(MyGlobals.lstNewItems != null)
    {
    MyGlobals.ListOfItemsToControl.AddRange(MyGlobals.lstNewItems);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-22
      • 1970-01-01
      • 2020-01-26
      • 2020-02-09
      • 2011-08-14
      • 1970-01-01
      • 1970-01-01
      • 2019-05-19
      相关资源
      最近更新 更多