Debido a un error que se corrigió en C # 4, se imprime el siguiente programa true
. (Pruébelo en 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()) { }
}
En VS2008 en modo Release, arroja una InvalidProgramException. (En modo de depuración, funciona bien)
En VS2010 Beta 2, no se compila (no probé Beta 1); Aprendí que de la manera difícil
¿Hay alguna otra forma de hacer this == null
en C # puro?
Respuestas:
Esta observación ha sido publicada en StackOverflow en otra pregunta el día de hoy.
La gran respuesta de Marc a esa pregunta indica que de acuerdo con las especificaciones (sección 7.5.7), no debería poder acceder
this
en ese contexto y la capacidad de hacerlo en el compilador C # 3.0 es un error. El compilador C # 4.0 se comporta correctamente de acuerdo con las especificaciones (incluso en Beta 1, este es un error de tiempo de compilación):fuente
: base(CheckNull())
si CheckNull no es estático, y tampoco debería poder incorporar una lambda vinculada a la instancia.this
en elCheckNull
método es legal. Lo que no es legal es la implícita este acceso en() => CheckNull()
, esencialmente() => this.CheckNull()
, que se ejecuta fuera del bloque de un constructor de instancias. Estoy de acuerdo en que la parte de la especificación que cito se centra principalmente en la legalidad sintáctica de lathis
palabra clave, y probablemente otra parte aborda este problema con mayor precisión, pero también es fácil extrapolar conceptualmente de esta parte de la especificación.La descompilación sin procesar (Reflector sin optimizaciones) del binario del modo de depuración es:
El método CompilerGenerated no tiene sentido; Si observa el IL (a continuación), está llamando al método en una cadena nula (!).
En el modo Release, la variable local se optimiza, por lo que intenta insertar una variable no existente en la pila.
(El reflector se bloquea al convertirlo en C #)
EDITAR : ¿Alguien (Eric Lippert?) Sabe por qué el compilador emite el
ldloc
?fuente
He tenido eso! (y obtuve pruebas también)
fuente
Esto no es un "error". Estás abusando del sistema de tipos. Se supone que nunca debe pasar una referencia a la instancia actual (
this
) a nadie dentro de un constructor.También podría crear un "error" similar llamando a un método virtual dentro del constructor de la clase base.
El hecho de que pueda hacer algo malo no significa que sea un error cuando lo muerde.
fuente
InvalidProgramException
.Podría estar equivocado, pero estoy bastante seguro de que si su objeto es
null
, nunca habrá un escenario donde sethis
aplique.Por ejemplo, ¿cómo llamarías
CheckNull
?fuente
this
es mutuamente excluyente de la posibilidad de ser nula, una especie de "Cogito, ergo sum" de la programación de computadoras. Por lo tanto, su deseo de usar la expresiónthis == null
y hacer que vuelva a ser verdadera me parece equivocada.No estoy seguro si esto es lo que estás buscando
ejemplo: UserID = CheckForNull (Request.QueryString ["UserID"], 147);
fuente