Рассмотрим этот код:
A a = null;
a.f(); //Will it throw NullReferenceException?
Вызовет ли вышеприведенное NullReferenceException
?
Ответ: это зависит от того, что такое f()
.
- Если это метод-член, то да, он выдаст исключение.
- Если это метод расширения, то нет, расширение не будет вызываться.
Это различие приводит к вопросу: как каждый тип метода реализуется и просматривается компиляторами C#? Кроме того, почему метод-член должен генерировать исключение, даже если он не обращается ни к каким данным-членам? Похоже, что компилятор C# заранее делает предположение, что метод-член будет обращаться к данным-членам, и поэтому выдает исключение, если объект имеет значение null, поскольку доступ к данным-членам с использованием нулевого объекта невозможен. Однако в случае метода расширения решение откладывается до тех пор, пока фактически не попытается получить доступ к данным участника, используя нулевую ссылку, только тогда выбрасывается исключение.
Насколько мое понимание верно? И если это так, то почему такая разница?
Да, я знаю, что если f()
является методом расширения, то a.f()
эквивалентно написанию AExt.f(a)
, поэтому последнее не должно генерировать исключение до тех пор, пока a
не будет использоваться для доступа к элементу. Но мое внимание в основном сосредоточено на реализациях компилятора (которые могут одинаково реализовывать даже методы-члены).
.IsNullOrEmpty
для строки, позволяяs.IsNullOrEmpty()
. - person Kirk Woll   schedule 03.09.2011s.IsNullOrEmpty()
правильно? Разве это не должно бытьstring.IsNullOrEmpty(s)
? Я думаю, что то, что вы написали, даже не скомпилируется! - person Nawaz   schedule 03.09.2011IsNullOrEmpty(this string s)
. - person svick   schedule 03.09.2011