是否有更好的方法来执行以下操作:
在继续循环
if (file.Headers != null)
{
foreach (var h in file.Headers)
{
//set lots of properties & some other stuff
}
}
简而言之,由于我的代码中出现了缩进级别,因此将foreach写入if中看起来有点难看。
是否会评估为
foreach(var h in (file.Headers != null))
{
//do stuff
}
可能?
答案 0 :(得分:97)
正如Rune建议的一个轻微的外观,你可以创建自己的扩展方法:
public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source)
{
return source ?? Enumerable.Empty<T>();
}
然后你可以写:
foreach (var header in file.Headers.OrEmptyIfNull())
{
}
根据品味更改名称:)
答案 1 :(得分:61)
假设file.Headers中的元素类型为T,则可以执行此操作
foreach(var header in file.Headers ?? Enumerable.Empty<T>()){
//do stuff
}
如果file.Headers为null,这将创建一个空的可枚举T。但是,如果文件类型是您拥有的类型,我会考虑更改Headers
的getter。 null
是未知的值,所以如果可能,而不是使用null作为“我知道没有元素”当null实际(/原始)应解释为“我不知道是否有任何元素”使用一个空集,表示您知道集合中没有元素。这也是干的,因为你不必经常进行空检查。
编辑作为对Jons建议的跟进,您还可以创建一个将上述代码更改为
的扩展方法foreach(var header in file.Headers.OrEmptyIfNull()){
//do stuff
}
如果您无法更改getter,这将是我自己的首选,因为它通过赋予操作名称(OrEmptyIfNull)
更清楚地表达了意图上面提到的扩展方法可能会使优化器无法进行某些优化检测。具体而言,可以消除与IList使用方法重载相关的那些
public static IList<T> OrEmptyIfNull<T>(this IList<T> source)
{
return source ?? Array.Empty<T>();
}
答案 2 :(得分:13)
坦率地说,我建议:只需要进行null
测试即可。 null
测试只是一个brfalse
或brfalse.s
;其他一切都将涉及更多的工作(测试,分配,额外的方法调用,迭代器上不必要的GetEnumerator()
,MoveNext()
,Dispose()
等。)
if
测试简单,明显且高效。
答案 3 :(得分:11)
迭代之前的“if”很好,很少有“漂亮”的语义可以使你的代码不那么可读。
无论如何,如果缩进扰乱了你,你可以改变if来检查:
if(file.Headers == null)
return;
只有在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
}
(用真实对象/类型替换集合)
答案 4 :(得分:3)
我正在为这些场景使用一个很好的小扩展方法:
public static class Extensions
{
public static IList<T> EnsureNotNull<T>(this IList<T> list)
{
return list ?? new List<T>();
}
}
鉴于Headers是类型列表,您可以执行以下操作:
foreach(var h in (file.Headers.EnsureNotNull()))
{
//do stuff
}
答案 5 :(得分:2)
使用Null-conditional Operator和ForEach(),它比标准的foreach循环工作得更快 您必须将集合转换为List。
listOfItems?.ForEach(item => // ... );
答案 6 :(得分:0)
对于某些情况,我更喜欢另一种通用变体,假设通常默认的集合构造函数返回空实例。
将此方法命名为NewIfDefault
会更好。它不仅对集合有用,因此类型约束IEnumerable<T>
可能是多余的。
public static TCollection EmptyIfDefault<TCollection, T>(this TCollection collection)
where TCollection: class, IEnumerable<T>, new()
{
return collection ?? new TCollection();
}