Из-за ошибки, исправленной в C # 4, печатается следующая программа true
. (Попробуйте в LINQPad)
void Main() { new Derived(); }
class Base {
public Base(Func<string> valueMaker) { Console.WriteLine(valueMaker()); }
}
class Derived : Base {
string CheckNull() { return "Am I null? " + (this == null); }
public Derived() : base(() => CheckNull()) { }
}
В VS2008 в режиме выпуска возникает исключение InvalidProgramException. (В режиме отладки работает нормально)
В VS2010 Beta 2 он не компилируется (Beta 1 не пробовал); Я узнал это на собственном горьком опыте
Есть ли другой способ сделать this == null
на чистом C #?
Ответы:
Это наблюдение было опубликовано на StackOverflow в другом вопросе сегодня.
Marc «s большой ответ на этот вопрос указывает на то, что в соответствии со спецификацией (раздел 7.5.7), вы не должны быть в состоянии получить доступ
this
в этом контексте и способности сделать это в C # 3.0 компилятор это ошибка. Компилятор C # 4.0 ведет себя правильно в соответствии со спецификацией (даже в Beta 1 это ошибка времени компиляции):источник
: base(CheckNull())
если CheckNull не является статическим, и, аналогично, вы не должны иметь возможность встроить привязанную к экземпляру лямбду.this
вCheckNull
методе является законным. Что не является законным является неявным это доступом в() => CheckNull()
, по существу() => this.CheckNull()
, который работает вне блока из конструктора экземпляра. Я согласен с тем, что часть спецификации, которую я цитирую, в основном сосредоточена на синтаксической законностиthis
ключевого слова, и, вероятно, другая часть решает эту проблему более точно, но ее также легко концептуально экстраполировать из этой части спецификации.Необработанная декомпиляция (Reflector без оптимизации) двоичного файла режима отладки:
Метод CompilerGenerated не имеет смысла; если вы посмотрите на IL (ниже), он вызывает метод для нулевой строки (!).
В режиме Release локальная переменная оптимизируется, поэтому она пытается поместить несуществующую переменную в стек.
(Рефлектор вылетает при превращении в C #)
РЕДАКТИРОВАТЬ : Кто-нибудь (Эрик Липперт?) Знает, почему компилятор выдает
ldloc
?источник
У меня было это! (и есть доказательства)
источник
Это не «ошибка». Это вы злоупотребляете системой типов. Вы никогда не должны передавать ссылку на текущий экземпляр (
this
) кому-либо в конструкторе.Я мог бы создать аналогичную «ошибку», вызвав также виртуальный метод в конструкторе базового класса.
То, что вы можете сделать что-то плохое, не означает, что это ошибка, когда вы ее укусите.
источник
InvalidProgramException
.Я могу ошибаться, но я почти уверен, что если ваша цель -
null
никогда не будет сценария, которыйthis
применим.Например, как бы вы позвонили
CheckNull
?источник
this
взаимоисключающей возможности быть нулевым - своего рода "Cogito, ergo sum" компьютерного программирования. Поэтому ваше желание использовать это выражениеthis == null
и когда-либо вернуть его истинность кажется мне ошибочным.Не уверен, что это то, что вы ищете
пример: UserID = CheckForNull (Request.QueryString ["UserID"], 147);
источник