这怎么可行(静态扩展?)

时间:2009-11-02 12:41:48

标签: c#

我在Marc Gravell的回答中看到了这一点,我只是看不出它是如何起作用的

static bool IsNullOrEmpty(this string value)
{    
    return string.IsNullOrEmpty(value);
}

不应该调用s.IsNullOrEmpty(),其中s为null,然后返回NullReferenceException?如果对象为空,如何取消引用对象以调用此处定义的函数?

或者这是一种结束猴子修补静态函数的方法吗?

2 个答案:

答案 0 :(得分:12)

扩展方法很神奇 - 它们只像实例方法一样看起来像,但是给出了扩展方法:

public static class StaticClass {
    public static void MyMethod(this SomeType obj) // note "this"
    {...}
}

然后:

instance.MyMethod();

汇编为:

StaticClass.MyMethod(instance);

你不会指望抛出一个NullReferenceException - 实际上并没有。{/ p>

这是双刃剑。在某些层面上它令人困惑,但它确实很有用。除非您有原因允许空值,否则最好在开始时添加自己的null-ref检查。另一个有用的:

public static void ThrowIfNull<T>(T value, string name) where T : class {
    if(value==null) throw new ArgumentNullException(name);
}
...
void SomeUnrelatedMethod(string arg) {
    arg.ThrowIfNull("arg");
}

答案 1 :(得分:2)

可以在空值上调用扩展方法。像这样的电话:

bool x = foo.IsNullOrEmpty();

只是在编译时翻译成

bool x = ExtensionClass.IsNullOrEmpty(foo);

不会隐式执行无效检查。这基本上是非常简单的语法糖。

虽然当你第一次看到它时这很奇怪,但对于完全像这样的测试来说非常方便。我也有一个扩展方法,我喜欢参数验证:

x.ThrowIfNull();
如果ArgumentNullException为空,

会抛出x