有没有这样做下面的一个更好的方式:
我需要为空的检查与循环继续之前对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
}
可能?
正如轻微化妆品除了符文的建议,你可以创建自己的扩展方法:
public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source)
{
return source ?? Enumerable.Empty<T>();
}
然后,你可以这样写:
foreach (var header in file.Headers.OrEmptyIfNull())
{
}
根据口味改名字:)
假设在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>();
}
坦率地说,我建议:刚大吃null
测试。 一个null
的测试只是一个brfalse
或brfalse.s
; 一切将涉及(测试,作业,额外的方法调用,不需要更多的工作GetEnumerator()
MoveNext()
Dispose()
的迭代器等)。
一个if
测试是简单的,明显的,高效的。
“如果”之前的迭代是好的,那几个“漂亮”的语义可以使代码的可读性。
无论如何,如果压痕扰乱你的,你可以改变,如果要检查:
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
}
(与你的真实对象/类型替换集合)
我使用这些方案的一个不错的扩展方法:
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
}
使用空,条件运算符和foreach(),它的工作原理比标准的foreach循环更快。
你要投的集合,虽然列出。
listOfItems?.ForEach(item => // ... );
对于某些情况下,我会稍微更倾向于另,普通变型,假设,作为一项规则,默认集合构造函数返回空实例。
这将是更好地命名这个方法NewIfDefault
。 它不仅能对集合是有用的,所以类型约束IEnumerable<T>
也许是多余的。
public static TCollection EmptyIfDefault<TCollection, T>(this TCollection collection)
where TCollection: class, IEnumerable<T>, new()
{
return collection ?? new TCollection();
}