可以在无对象上调用扩展方法吗?

时间:2013-11-28 12:51:44

标签: c# extension-methods

为什么以下代码有效?

呼叫:

SomeObject sO = null;
bool test = sO.TestNull();

代码:

public static bool TestNull(this SomeObject sO)
{
    return sO == null;
}

这是允许工作还是只是一个错误?

4 个答案:

答案 0 :(得分:13)

  

这是允许工作还是只是一个错误?

您编辑问题后的代码(拨打s0.TestNull()而不是null.TestNull())是有效的,是的。

扩展方法只是 语法糖,用于调用静态方法,就好像它们是实例方法一样。所以打电话:

s0.TestNull()

转换为

ClassContainingExtensionMethod.TestNull(s0)

......就是这样。不会自动执行无效检查。

这实际上非常有用 - 想象string.IsNullOrEmpty是否是扩展方法 - 然后而不是写作:

if (string.IsNullOrEmpty(foo))

你可以写得更具可读性:

if (foo.IsNullOrEmpty())

然而,不应该掉以轻心 - 大多数扩展方法应该抛出ArgumentNullException如果第一个参数具有空值,那些不应该非常清楚它。 (这样的方法在名称中的某处包含Null应该是相对罕见的。)

答案 1 :(得分:6)

假设你的意思

bool test = sO.TestNull();

然后答案就是静态函数不需要对象的实例。另外,调用扩展函数只是用参数调用函数的语法糖。

编辑:

我建议您也阅读Jon Skeet's answer

答案 2 :(得分:4)

代码应为bool test = sO.TestNull();。是的,这应该是有效的。

您正在使用函数扩展对象,如果对象是null或包含值,则无关紧要。它与编写SomeStaticClass.TestNull(sO);

基本相同

答案 3 :(得分:2)

正如乔恩和其他人已经指出的那样,这是标准行为。它可能对

很有用
  • 在执行此操作之前引发事件并检查无效的扩展方法
  • 提供 Maybes 链的扩展方法,其中链的每个部分都可以为空。

很久以前我想知道是否it is OK to send messages to null references但是时间已经表明这是一个非常务实和有用的,特别是考虑到在其他语言中,空引用根本不存在。