Design choice: Do I want extension methods to throw exceptions on null? [duplicate]

橙三吉。 提交于 2019-12-05 05:40:10
James Michael Hare

Microsoft throws an ArgumentNullException if the collections invoked in LINQ are empty. This is really more a matter of style, but is consistent with the way extension methods are supposed to behave.

@m0sa is right though in that you'll get a null reference from your foreach, but I would say check up top and throw ArgumentNullException. That way you'll be on par with what LINQ does.

For example, if you look at Any() in a decompiler you see:

public static bool Any<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        if (enumerator.MoveNext())
        {
            return true;
        }
    }
    return false;
}

You should definitely do null checking and throw ArgumentNullException to avoid hard to understand NullReferenceExceptions inside your code.

In general I would avoid to treat null as en "empty" IEnumerable<T>. Just use Enumerable.Empty<T>() instead to avoid special cases for a null collection.

If you decide to do null checking in your extension method you should consider doing that "eagerly". If you are using yield return inside your extension method none of it will actually be evaluated until iteration begins. You split your extension method into two parts. The "eager" part where arguments are checked and the "lazy" that yield return elements.

First of all: I'm quite sure that there will be an NullReferenceException if collection is null. So that part of your question is no problem at all. Regarding the rest: Do you gain anything by checking for null and throwing a different exception? In my opinion: no! So I would not clutter my code with checks that do not help at all.

If the collection argument was null I would throw a NullReferenceException. This comes from thinking about how it would behave if it was null, and Each<T> happened to be just a regular method--a NullReferenceException being thrown is what I would expect to happen.

EDIT: Based on Martin's comment and some further research on this, I take back what I said. It seems that a NullReferenceException shouldn't be thrown in this case, as Microsoft recommends using an ArgumentNullException instead.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!