您在foreach循环空(Check for null in foreach loop)

2019-06-26 15:20发布

有没有这样做下面的一个更好的方式:
我需要为空的检查与循环继续之前对file.Headers发生

if (file.Headers != null)
{
  foreach (var h in file.Headers)
  {
   //set lots of properties & some other stuff
  }
}

总之,它看起来有点难看,如果由于压痕的水平在我的代码发生的事情写在里面在foreach。

是什么,将评估为

foreach(var h in (file.Headers != null))
{
  //do stuff
}

可能?

Answer 1:

正如轻微化妆品除了符文的建议,你可以创建自己的扩展方法:

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

然后,你可以这样写:

foreach (var header in file.Headers.OrEmptyIfNull())
{
}

根据口味改名字:)



Answer 2:

假设在file.Headers元素的类型为T,你可以这样做

foreach(var header in file.Headers ?? Enumerable.Empty<T>()){
  //do stuff
}

如果file.Headers为null,这将创建T的空枚举。 如果文件类型是你自己我会,但是,考虑改变吸气型Headers代替。 null是未知的值,所以如果可能的话,而不是使用null作为“我知道有没有元素”时,空实际上(/原)应被解释为“我不知道是否有任何元素”用一个空集,表明你知道在一组没有任何元素。 这也将是DRY'er,因为你将不必为经常做的空检查。

编辑为跟进容斯的建议,你也可以创建一个扩展方法改变上面的代码

foreach(var header in file.Headers.OrEmptyIfNull()){
  //do stuff
}

在你不能改变吸气的情况下,这将是我自己的首选,因为它给予操作的名称表达的意图更加清晰(OrEmptyIfNull)

上面提到的扩展方法可能使某些优化无法优化检测。 具体而言,那些使用方法重载此有关的IList可以消除

public static IList<T> OrEmptyIfNull<T>(this IList<T> source)
{
    return source ?? Array.Empty<T>();
}


Answer 3:

坦率地说,我建议:刚大吃null测试。 一个null的测试只是一个brfalsebrfalse.s ; 一切将涉及(测试,作业,额外的方法调用,不需要更多的工作GetEnumerator() MoveNext() Dispose()的迭代器等)。

一个if测试是简单的,明显的,高效的。



Answer 4:

“如果”之前的迭代是好的,那几个“漂亮”的语义可以使代码的可读性。

无论如何,如果压痕扰乱你的,你可以改变,如果要检查:

if(file.Headers == null)  
   return;

你会得到foreach循环只有当在头的值为true。

另一种选择我能想到的是使用foreach循环内的空合并运算,并完全避免无效检查。 样品:

List<int> collection = new List<int>();
collection = null;
foreach (var i in collection ?? Enumerable.Empty<int>())
{
    //your code here
}

(与你的真实对象/类型替换集合)



Answer 5:

我使用这些方案的一个不错的扩展方法:

  public static class Extensions
  {
    public static IList<T> EnsureNotNull<T>(this IList<T> list)
    {
      return list ?? new List<T>();
    }
  }

由于头的类型列表中,你可以做以下操作:

foreach(var h in (file.Headers.EnsureNotNull()))
{
  //do stuff
}


Answer 6:

使用空,条件运算符和foreach(),它的工作原理比标准的foreach循环更快。
你要投的集合,虽然列出。

   listOfItems?.ForEach(item => // ... );


Answer 7:

对于某些情况下,我会稍微更倾向于另,普通变型,假设,作为一项规则,默认集合构造函数返回空实例。

这将是更好地命名这个方法NewIfDefault 。 它不仅能对集合是有用的,所以类型约束IEnumerable<T>也许是多余的。

public static TCollection EmptyIfDefault<TCollection, T>(this TCollection collection)
        where TCollection: class, IEnumerable<T>, new()
    {
        return collection ?? new TCollection();
    }


文章来源: Check for null in foreach loop