所以我经常遇到这种情况……Do.Something(…)返回一个空集合,如下所示:

int[] returnArray = Do.Something(...);

然后,我尝试像这样使用这个集合:

foreach (int i in returnArray)
{
    // do some more stuff
}

我只是好奇,为什么foreach循环不能操作一个空集合?在我看来,零次迭代将被一个空集合执行是合乎逻辑的……相反,它抛出一个NullReferenceException。有人知道为什么吗?

这很烦人,因为我使用的api不清楚它们返回什么,所以我最终到处都是if (someCollection != null)。


当前回答

这是Do.Something()的错。这里的最佳实践是返回一个大小为0的数组(这是可能的),而不是null。

其他回答

另一个扩展方法来解决这个问题:

public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
    if(items == null) return;
    foreach (var item in items) action(item);
}

以几种方式消费:

(1)采用接受T的方法:

returnArray.ForEach(Console.WriteLine);

(2)用表达式表示:

returnArray.ForEach(i => UpdateStatus(string.Format("{0}% complete", i)));

(3)采用多行匿名方法

int toCompare = 10;
returnArray.ForEach(i =>
{
    var thisInt = i;
    var next = i++;
    if(next > 10) Console.WriteLine("Match: {0}", i);
});

foreach循环调用GetEnumerator方法。 如果集合为空,此方法调用将导致NullReferenceException。

返回一个空集合是不好的做法;你的方法应该返回一个空的集合。

这是Do.Something()的错。这里的最佳实践是返回一个大小为0的数组(这是可能的),而不是null。

因为在幕后,foreach获取了一个枚举数,等价于:

using (IEnumerator<int> enumerator = returnArray.getEnumerator()) {
    while (enumerator.MoveNext()) {
        int i = enumerator.Current;
        // do some more stuff
    }
}
SPListItem item;
DataRow dr = datatable.NewRow();

dr["ID"] = (!Object.Equals(item["ID"], null)) ? item["ID"].ToString() : string.Empty;