在foreach循环中检查null

Emi*_*nem 79 c# foreach null loops

有没有更好的方法来执行以下操作:
我需要在继续循环之前检查file.Headers上的null

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

简而言之,由于我的代码中发生缩进的程度,因此将foreach写入if中看起来有点难看.

是值得评价的东西

foreach(var h in (file.Headers != null))
{
  //do stuff
}
Run Code Online (Sandbox Code Playgroud)

可能?

Jon*_*eet 107

正如Rune建议的一个轻微的外观,你可以创建自己的扩展方法:

public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source)
{
    return source ?? Enumerable.Empty<T>();
}
Run Code Online (Sandbox Code Playgroud)

然后你可以写:

foreach (var header in file.Headers.OrEmptyIfNull())
{
}
Run Code Online (Sandbox Code Playgroud)

根据口味更改名称:)


Run*_* FS 68

假设file.Headers中的元素类型为T,则可以执行此操作

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

如果file.Headers为null,这将创建一个空的可枚举T.如果文件类型是您拥有的类型,我会考虑更改getter Headers.null是未知的值,所以如果可能,而不是使用null作为"我知道没有元素"当null实际(/原始)应该被解释为"我不知道是否有任何元素"使用空集来显示你知道集合中没有元素.这也是DRY'er,因为你不必经常进行空检查.

编辑作为Jons建议的后续,您还可以创建一个扩展方法,将上面的代码更改为

foreach(var header in file.Headers.OrEmptyIfNull()){
  //do stuff
}
Run Code Online (Sandbox Code Playgroud)

如果您无法更改getter,这将是我自己的首选,因为它通过赋予操作名称(OrEmptyIfNull)更清楚地表达了意图


Mar*_*ell 16

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

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

  • 在我问这个问题并需要实施一些性能增强多年之后,我只是对这个 Marc 做一个简短的说明,你的建议非常有用。谢谢 (4认同)

Tam*_*mir 11

迭代之前的"if"很好,很少有"漂亮"的语义可以使你的代码不那么可读.

无论如何,如果缩进扰乱了你,你可以改变if来检查:

if(file.Headers == null)  
   return;
Run Code Online (Sandbox Code Playgroud)

并且只有在headers属性中存在true值时才会进入foreach循环.

我能想到的另一个选择是在foreach循环中使用null-coalescing运算符,并完全避免空值检查.样品:

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

(用真实对象/类型替换集合)


Edd*_*die 6

2022年的最佳答案应该是:

foreach (var h in file.Headers ?? Enumerable.Empty<T>())
{
    //do stuff
}
Run Code Online (Sandbox Code Playgroud)

替换T为您的数据类型。如果 file.Headers 是一个数组,请使用Array.Empty<T>()而不是Enumerable.Empty<T>()


And*_*ski 5

使用空条件运算符和ForEach(),其工作速度比标准foreach循环快。
您必须将集合强制转换为List。

   listOfItems?.ForEach(item => // ... );
Run Code Online (Sandbox Code Playgroud)

  • 请围绕您的答案添加一些解释,明确说明此解决方案的原因,而不仅仅是单行代码 (2认同)