所以我经常遇到这种情况... Do.Something(...)
返回一个null集合,如下所示:
int[] returnArray = Do.Something(...);
Run Code Online (Sandbox Code Playgroud)
然后,我试着像这样使用这个集合:
foreach (int i in returnArray)
{
// do some more stuff
}
Run Code Online (Sandbox Code Playgroud)
我只是好奇,为什么foreach循环不能对null集合进行操作?对我来说似乎合乎逻辑的是,0迭代将使用null集合执行...而是抛出一个NullReferenceException
.任何人都知道为什么会这样?
这很烦人,因为我正在处理那些不确定它们返回的API,所以我最终if (someCollection != null)
到处都是......
编辑:谢谢大家解释foreach
使用GetEnumerator
,如果没有枚举器,foreach会失败.我想我问为什么语言/运行时在抓取枚举器之前不能或不会进行空检查.在我看来,这种行为仍然会得到很好的定义.
Rob*_*cus 239
嗯,简短的回答是"因为这是编译器设计者设计它的方式." 但实际上,您的集合对象是null,因此编译器无法让枚举器循环遍历集合.
如果你真的需要做这样的事情,试试null合并运算符:
int[] array = null;
foreach (int i in array ?? Enumerable.Empty<int>())
{
System.Console.WriteLine(string.Format("{0}", i));
}
Run Code Online (Sandbox Code Playgroud)
SLa*_*aks 143
一个foreach
循环中调用的GetEnumerator
方法.
如果是集合null
,则此方法调用将导致a NullReferenceException
.
返回null
集合是不好的做法; 你的方法应该返回一个空集合.
Ree*_*sey 47
空集合与集合的空引用之间存在很大差异.
在foreach
内部使用时,这是调用IEnumerable的GetEnumerator()方法.当引用为null时,这将引发此异常.
但是,空IEnumerable
或者是完全有效的IEnumerable<T>
.在这种情况下,foreach不会"迭代"任何东西(因为集合是空的),但它也不会抛出,因为这是一个完全有效的场景.
编辑:
就个人而言,如果您需要解决此问题,我建议使用扩展方法:
public static IEnumerable<T> AsNotNull<T>(this IEnumerable<T> original)
{
return original ?? Enumerable.Empty<T>();
}
Run Code Online (Sandbox Code Playgroud)
然后你可以打电话:
foreach (int i in returnArray.AsNotNull())
{
// do some more stuff
}
Run Code Online (Sandbox Code Playgroud)
Dev*_*esh 12
它是长期回答,但我试图通过以下方式做到这一点,以避免空指针异常,并可能对使用C#null check运算符的人有用?
//fragments is a list which can be null
fragments?.ForEach((obj) =>
{
//do something with obj
});
Run Code Online (Sandbox Code Playgroud)
Jay*_*Jay 10
解决此问题的另一种扩展方法:
public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
if(items == null) return;
foreach (var item in items) action(item);
}
Run Code Online (Sandbox Code Playgroud)
以几种方式消费:
(1)采用以下方法T
:
returnArray.ForEach(Console.WriteLine);
Run Code Online (Sandbox Code Playgroud)
(2)用表达式:
returnArray.ForEach(i => UpdateStatus(string.Format("{0}% complete", i)));
Run Code Online (Sandbox Code Playgroud)
(3)采用多线匿名方法
int toCompare = 10;
returnArray.ForEach(i =>
{
var thisInt = i;
var next = i++;
if(next > 10) Console.WriteLine("Match: {0}", i);
});
Run Code Online (Sandbox Code Playgroud)
只需编写一个扩展方法来帮助您:
public static class Extensions
{
public static void ForEachWithNull<T>(this IEnumerable<T> source, Action<T> action)
{
if(source == null)
{
return;
}
foreach(var item in source)
{
action(item);
}
}
}
Run Code Online (Sandbox Code Playgroud)
因为null集合与空集合不同.空集合是没有元素的集合对象; null集合是不存在的对象.
这里有一些尝试:声明两个任何类型的集合.正常初始化一个,使其为空,并为另一个赋值null
.然后尝试将对象添加到两个集合中,看看会发生什么.
归档时间: |
|
查看次数: |
107125 次 |
最近记录: |