Siempre he pensado que es imposible que this
sea nulo dentro del cuerpo del método de instancia. Seguir un programa simple demuestra que es posible. ¿Es esto un comportamiento documentado?this == null método de instancia .NET - ¿por qué es posible?
class Foo
{
public void Bar()
{
Debug.Assert(this == null);
}
}
public static void Test()
{
var action = (Action)Delegate.CreateDelegate(typeof (Action), null, typeof(Foo).GetMethod("Bar"));
action();
}
ACTUALIZACIÓN
Estoy de acuerdo con las respuestas diciendo que es como se documenta este método. Sin embargo, realmente no entiendo este comportamiento. Especialmente porque no es como se diseña C#.
que habíamos conseguido un informe de alguien (probablemente uno de los grupos .NET usando C# (pensaban que aún no se denomina C# en ese momento)) que tenía código escrito que llama a un método en un nulo puntero, pero no lo hicieron obtener una excepción porque el método no accedió a ningún campo (es decir, "this" era nulo, pero no había nada en el método utilizado). Ese método luego llamó a otro método que usó el punto y arrojó una excepción , y se produjo un poco de arañazo en la cabeza. Después de que lo calcularon , nos enviaron una nota al respecto. Pensamos que poder llamar a un método en una instancia nula era un poco extraño. Peter Golde hizo algunas pruebas para ver cuál era el impacto en el rendimiento de usar siempre callvirt, y fue lo suficientemente pequeño como para decidir para realizar el cambio.
http://blogs.msdn.com/b/ericgu/archive/2008/07/02/why-does-c-always-use-callvirt.aspx
Consulte mi respuesta para ver si CLR fue diseñado intencionalmente de este modo en .NET 1.0.El artículo que cita es sobre una situación diferente (no delegada), que sería una optimización del compilador: reemplazar un 'callvirt' por una llamada directa cuando el tipo de instancia se puede determinar estáticamente. Tenga en cuenta que la razón por la cual CLR tiene que lanzar 'NullReferenceException' durante' callvirt' es la necesidad de una búsqueda VMT basada en la referencia 'this'; no solo un deseo semántico de verificar la referencia. –
Relacionado: http://stackoverflow.com/q/3143498/158779 –
En mi humilde opinión, es desafortunado que no haya una forma estándar (quizás a través de atributos) para especificar que un método debe invocarse con 'call' en lugar de' callvirt', ya que eso hubiera permitido que los tipos que encapsulan valores [como 'cadena'] tengan miembros que puedan operar en ubicaciones de almacenamiento con valores predeterminados. Diciendo 'if (someString.IsNullOrEmpty)' sería mucho más limpio en mi humilde opinión que 'if (String.IsNullOrEmpty (someString))'. – supercat