扩展方法是否需要抛出NullReferenceException?

8

If I define an extension method such as this:

static public String ToTitleCase(this string instance, CultureInfo culture)
{
    if (instance == null)
        throw new NullReferenceException();

    if (culture == null)
        throw new ArgumentNullException("culture");

    return culture.TextInfo.ToTitleCase(instance);
}

我需要检查字符串实例是否为null并自己抛出null引用异常吗?还是CLR在这种情况下像处理实例方法一样处理扩展方法,并且为我处理检查/抛出?

我知道扩展方法只是静态方法的语法糖,也许C#编译器会在编译时添加检查?请澄清一下 :)


2
重複的問題提供了一些贊成 ANE 與 NRE 的好理由以及其他細節。 - user166390
2个回答

36

不可以。你绝对不应该手动抛出 NullReferenceException,这个异常只能由框架自己抛出。

在这种情况下,你应该同时抛出 ArgumentNullException 对于instanceculture参数:

static public String ToTitleCase(this string instance, CultureInfo culture)
{
    if (instance == null)
        throw new ArgumentNullException("instance");

    if (culture == null)
        throw new ArgumentNullException("culture");

   return culture.TextInfo.ToTitleCase(instance);
}

根据 NullReferenceException 文档

注意,应用程序抛出的是 ArgumentNullException 异常,而不是在此处讨论的 NullReferenceException 异常。


5
我认为你的“从不”需要更强的强调。 - R. Martinho Fernandes
"never"有特定的原因吗?如果NRE不是由于参数为null而导致的呢?(虽然情况不同,但为什么要用“never”?) - user166390
1
在这个特定的例子中,由于字符串没有被取消引用,所以框架永远不会抛出空引用异常。我只是想知道,如果我自己抛出一个NullReferenceException是否对使用此方法的人更一致,例如:String foo = null; foo = foo.SubString(0, 10); // NullReferenceException foo = foo.ToTitleCase(c); // ArgumentNullException... 这让人困惑吗? - MattDavey
1
@Matt:扩展方法仍然只是一个静态方法,而“this”参数仍然只是该方法的参数。在我看来,抛出NRE而不是ANE会更加混乱和不一致;没有对null进行解引用,但你已经传递了一个null参数。 - LukeH
2
也许你应该提到这个文档:创建和抛出异常 - C# 编程指南 | Microsoft Docs - walterlv
显示剩余3条评论

1

绝对不是这样的。然而,“快速失败”和一些人忘记的是“有益的失败”。然而,我认为不抛出ArgumentNullException的原因(关于NullReferenceException的辩论留给其他帖子)是有限的,并且通常与过度聪明有关 :-) 一个假设的用例可能是IsNullOrEmpty只要它确实有用并使代码更清晰:就去做吧。

CLR没有检查。 就运行时而言,它只是将(可能为空)参数传递给静态方法。其余都是糖果 - 其中没有任何糖果涉及添加额外的空值检查 :-)

愉快的编码。


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