2009-11-02 2 views
4

Я видел это в ответ Марк Gravell, и я просто не вижу, как это будет работатьКак это может работать (статическое расширение?)

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

В случае, если не призыв к s.IsNullOrEmpty () где s равно null, а затем возвращает исключение NullReferenceException? Как вы можете удалить ссылку на объект, чтобы вызвать функцию, определенную здесь, если объект имеет значение null?

Или это какой-то способ для обхода обезьяны статической функции?

ответ

12

Методы расширения магия - они только выглядят как методы экземпляра, но данный метод расширения:

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

затем:

instance.MyMethod(); 

компилирует:

StaticClass.MyMethod(instance); 

И вы бы не ожидали, что бросить NullReferenceException - и это не так.

Это обоюдоострый цвет. На некоторых уровнях это запутывает, но может быть очень полезно. Было бы хорошей практикой добавить свою собственную проверку нулевого ref в начале, если у вас нет причины , чтобы разрешить null. Другой полезный:

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"); 
} 
+0

В первом предложении вы, скорее всего, имеете в виду «методы расширения» вместо «статических методов» ... –

+0

d'oh! В самом деле. Уточнено. Большие уши мне. –

2

Методы расширения можно вызывать на нулевых значениях. Вызов, как это:

bool x = foo.IsNullOrEmpty(); 

просто переведен во время компиляции в

bool x = ExtensionClass.IsNullOrEmpty(foo); 

Без проверки недействительности выполняется неявно. Это очень простой синтаксический сахар, в основном.

Хотя это странно, когда вы впервые видите это, это очень удобно для тестов именно так. У меня также есть метод расширения мне нравится для проверки параметров:

x.ThrowIfNull(); 

который бросает ArgumentNullException если x является недействительным.

+0

Методы расширения могут быть вызваны только на нулевые значения, если для компилятора не очевидно, что они равны нулю. AFAIK, '((string) null) .Extension()' не будет компилироваться, поэтому не 'default (string) .Extension()'. –

+1

@Stefan: Я только что попробовал, и оба компилируются. Последний выдает вводящее в заблуждение предупреждение (что является неудачным), но первый компилирует без каких-либо проблем. –

Смежные вопросы