设计选择:'ToArray()'LINQ扩展为null集合抛出异常的任何好理由?

时间:2012-02-16 19:13:03

标签: linq

不出所料,以下代码会抛出ArgumentNullException

IEnumerable<string> collection = null;
string[] collectionViewAsAnArray = collection.ToArray();

这种看起来一见钟情......但是并不是说不一致,认为返回null可能是一个合理的替代(会计ToArray()是一种扩展方法,因此即使在null上也可以调用它。

虽然我承认,这样,扩展行为就像一个真正的方法,我不禁发现其他方法真的很聪明......但这可能会导致其他问题?

2 个答案:

答案 0 :(得分:3)

授予IEnumerable是集合中使用的接口,但底层实现是对象,并且您已将collection变量设置为指向null,因此例外。

另一方面,如果您使用以下内容初始化collection

IEnumerable<string> collection = Enumerable.Empty<string>();

OR

IEnumerable<string> collection = new List<string>();

您可以使用空列表对象。引发ArgumentNullException异常是因为集合参数实际上是null,而ToArray()正在尝试对其进行操作。从逻辑上讲,无论如何,这是唯一的设计选择。

修改

另一方面,在实践中,当我的类方法的返回类型应该返回IEnumerable<T>时,我已经有意识地决定总是返回有效的IEnumerable<T>

例如;看起来像IEnumerable<T> GetAll()的方法签名总是会返回一个有效的可枚举项。如果没有任何内容可以返回,那么我将返回return Enumerable.Empty<T>();

与我不同的是,GetAll()不会对集合参数采取行动。你可以真正看到这个,因为集合实际上只是方法的一个参数,如果你将一个null参数传递给常规方法,你可能会抛出一个ArgumentNullException


简短回答是您的collection变量是预期的 参数(或参数){{1} }方法,它是ToArray()所以抛出null

是有意义的

答案 1 :(得分:2)

为什么要将错误推送到代码中的其他位置?如果您希望某些内容可以为null,请在使用之前进行检查。否则,在您的假设为假的位置,即当您尝试将其转换为数组时,将完全错误抛出。

我知道当你进行链接操作时可能会引起争议,但在这种情况下,我发现使用空IEnumerable而不是null更容易。