我应该检查传递的list<T>是否为null吗?

3

一个扩展方法需要一个开放的泛型 IEnumerable。

我应该在方法内部检查列表是否为空吗?

我认为列表永远不应该为空,但是可以有 count == 0。

您如何处理这种情况?

更新:

我忘记提到该方法是一个递归方法,其中列表被递归调用/传递了。

4个回答

6

这要看情况。

如果无法处理空列表,则需要测试并引发ArgumentNullException异常:

if (list == null)
{
    throw new ArgumentNullException("some suitable message");
}

如果列表为空与列表存在但没有元素相当,则应允许这种情况。
if (list == null || list.Count() == 0)
{
    .....
}

1

是的,你应该检查一下。在LINQ中,这也是一个相当常见的模式,特别是在这种情况下抛出异常。

public static void MyExtension<T>(this IEnumerable<T> source)
{
    if (source == null)
    {
        throw new ArgumentNullException("source");
    }

    // ...
}

处理空列表比处理空实例的列表要容易得多。这样想吧; 没有项目的列表只是一个空集合 - 相当常见的情况。而为空的列表代表什么呢?异常情况,应该像处理异常一样处理。
更新:
我查看了微软关于我的猜测的说法,即抛出ANE是常见模式(与让CLR抛出NRE相反-在某些情况下可能过于模糊),并且似乎是正确的。我们可以在ANE documentation page中找到以下内容:
“提供ArgumentNullException(...)以便应用程序代码可以区分由空参数引起的异常和由非空参数引起的异常。”
稍后,在框架设计指南的Exception Throwing部分中:
请通过抛出异常来报告执行失败。如果成员不能成功地完成其设计任务,那应该被视为执行失败并且应该抛出异常
在您的情况下,由于您提到您的方法绝不能接受空列表参数,这是一个简单的执行失败情况。

我已经更新了我的问题。如果框架在调用方法时会抛出 Null Exception,为什么要抛出 Argument Exception? - Pascal
你在ChrisF之前就提醒了他ArgumentNullException的问题(他后来编辑了他的解决方案) :) - Pascal
@Pascal:谢谢。我查了一些设计指南,似乎抛出ANE确实是推荐的模式。请看我的更新答案。 - k.m
@Pascal:如果你在整个项目中使用它们,那肯定是有意义的(尤其是考虑到它们与自动化测试或文档生成工具非常配合)。这是一个整个项目范围内的决策(是否使用CC)。仅在单个方法/案例中应用它可能不是最好的主意。 - k.m

0
通常情况下,我想要得到一个异常,但有时(特别是在使用第三方代码时),将null作为空实例更加方便:
public static class FrameworkExtensions
{
    /// <summary>
    /// null tolerant access to a Collection
    /// 
    /// usage:
    /// foreach (int i in returnArray.AsNotNull())
    /// {
    ///     // do some more stuff
    /// }
    /// </summary>
    /// <typeparam name="T">Type of collection</typeparam>
    /// <param name="original"></param>
    /// <returns></returns>
    public static IEnumerable<T> AsNotNull<T>(this IEnumerable<T> original)
    {
        return original ?? new T[0];
    }
}

-1

更新:

我相信你的意思是将列表作为方法参数传递,但在这种情况下解决方案很明显(甚至检查对象本身):

public static void ExtensionMethod<T>(this IEnumerable<T> list,
                                      IEnumerable<T> anOtherlist)
{
    bool listItselfNotNull = list != null;
    bool anOtherListNotNull = anOtherList != null;
}

2
你可以在空对象上调用扩展方法。 - Hans Kesting
2
可以在null上使用扩展方法。 - Lukazoid
1
哇,好棒的消息,谢谢大家!对于-1,它是值得的:)。已删除“null-tip”。 - sll

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接