如何避免在迭代集合为 null 时抛出的空引用异常?
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何避免在迭代集合为 null 时抛出的空引用异常?相关的知识,希望对你有一定的参考价值。
咨询区
Polaris878
我在遍历集合时,经常会遇到集合为 null
的情况,比如下面这样:
int[] returnArray = Do.Something(...);
拿到数组后,接下来我用下面的方式进行遍历。
foreach (int i in returnArray)
// do some more stuff
说实话,我非常好奇,为什么就不能在 null 集合中进行迭代呢?我觉得从逻辑上来说,null集合意味着没有迭代项而已,但框架却抛出了 NullReferenceException
异常,真的难以理解。
真的很让我苦恼,每次在调用 api 的时候我也不清楚对方确切返回值,只能每次都用 if (someCollection != null)
做一个前置判断。
回答区
Reed Copsey
首先你要明白 空集合
和 null
有着本质的区别,foreach
在内部调用的是 IEnumerable 的 GetEnumerator()
方法,而 null 哪里有呢?自然就会引发 NullReferenceException
异常,不是吗?
要想解决,方法也挺多的,大概有如下几种。
Enumerable.Empty<T>()
Empty()扩展方法的内部是一个 EmptyPartition
类,它的 MoveNext() 直接返回 false,是空集合的绝佳替代方案,源码如下:
internal sealed class EmptyPartition<TElement>
public bool MoveNext()
return false;
在使用上,非常推荐封装为一个扩展方法。
public static IEnumerable<T> AsNotNull<T>(this IEnumerable<T> original)
return original ?? Enumerable.Empty<T>();
foreach (int i in returnArray.AsNotNull())
// do some more stuff
使用
?.
可空运算符
空检查操作符 ?.
也是一个非常好的方式,参考如下代码:
//fragments is a list which can be null
fragments?.ForEach((obj) =>
//do something with obj
);
封装 action
可以将 foreach 中的迭代逻辑封装到 action 中,并在扩展方法上做防御性检查即可,参考如下代码:
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);
点评区
这确实是一个很搞的问题,相信很多朋友在项目开发中肯定会遇到,设计模式也有类似的 空对象模式
,大佬提供的这三种方式很不错,学习了。
以上是关于如何避免在迭代集合为 null 时抛出的空引用异常?的主要内容,如果未能解决你的问题,请参考以下文章
将 pyspark df 转换为 pandas 时抛出的异常是等待结果
Pageable 不能为 null 在 Spring Data-Solr 中使用组功能时抛出异常
如何避免在ChannelReader.WaitToReadAsync时抛出InvalidOperationException?