c# - studio - referencia a objeto no establecida como instancia de un objeto wcf
Referencia de objeto no establecida en una instancia de un objeto. ¿Por qué no muestra.NET qué objeto es `nulo`? (5)
En relación con este mensaje de excepción .hand no administrado:
Referencia a objeto no establecida como instancia de un objeto.
¿Por qué .NET no muestra qué objeto es null
?
Sé que puedo verificar el null
y resolver el error. Sin embargo, ¿por qué .NET no ayuda a señalar qué objeto tiene una referencia nula y qué expresión desencadenó la NullReferenceException
?
¿Cómo se ve el mensaje de error en el siguiente caso?
AnyObject.GetANullObject().ToString();
private object GetANullObject()
{
return null;
}
¡No hay nombres de variables para informar aquí!
(Para obtener información sobre el nuevo asistente de excepciones en Visual Studio 2017, vea el final de esta respuesta)
Considera este código:
String s = null;
Console.WriteLine(s.Length);
Esto lanzará una NullReferenceException
en la segunda línea y desea saber por qué .NET no le dice que era s
que era nulo cuando se lanzó la excepción.
Para comprender por qué no obtienes esa información, debes recordar que no es la fuente de C # la que se ejecuta sino IL:
IL_0001: ldnull IL_0002: stloc.0 // s IL_0003: ldloc.0 // s IL_0004: callvirt System.String.get_Length IL_0009: call System.Console.WriteLine
Es el callvirt
operación callvirt
que arroja la NullReferenceException
y lo hace cuando el primer argumento en la pila de evaluación es una referencia nula (la que se cargó usando ldloc.0
).
Si .NET debería poder decir que era una referencia nula, de alguna manera debería rastrear que el primer argumento en la pila de evaluación se originó en el formulario s
. En este caso, es fácil para nosotros ver que es s
que fue nulo, pero ¿qué ocurre si el valor es un valor de retorno de otra llamada a función y no está almacenado en ninguna variable? De todos modos, este tipo de información no es lo que desea hacer un seguimiento en una máquina virtual como la máquina virtual .NET.
Para evitar este problema, sugiero que realice una comprobación nula de argumentos en todas las llamadas a métodos públicos (a menos que, por supuesto, permita la referencia nula):
public void Foo(String s) {
if (s == null)
throw new ArgumentNullException("s");
Console.WriteLine(s.Length);
}
Si se pasa null al método, se obtiene una excepción que describe con precisión cuál es el problema (que s
es nulo).
Cuatro años después, Visual Studio 2017 ahora tiene un nuevo asistente de excepción que tratará de decir qué es nulo cuando se lanza una NullReferenceException
. Incluso puede proporcionarle la información requerida cuando el valor de retorno de un método es nulo:
Tenga en cuenta que esto solo funciona en una compilación DEBUG.
Buena pregunta. El cuadro de mensaje es inútil. Incluso si está enterrado a una milla de profundidad de la definición de referencias, alguna clase, ensamblaje, archivo u otra información sería mejor de lo que ofrecen actualmente (léase: mejor que nada).
Su mejor opción es ejecutarlo en el depurador con información de depuración, y su IDE se romperá en la línea ofensiva (lo que demuestra claramente que de hecho hay información útil disponible).
Bueno, eso depende de los ingenieros de Microsoft para responder. Pero obviamente puede usar un depurador y agregar vigilancia para averiguar cuál de ellos tiene un problema.
Sin embargo, la excepción es NullReferenceException
que significa que la referencia no existe . No puede obtener el objeto que no ha sido creado en absoluto.
but why .NET don''t tell us which object is null?
Porque no sabe qué objeto es nulo. ¡El objeto simplemente no existe!
Igual es el caso cuando digo que C # se compila con el código .NET IL. El código .NET IL no conoce los nombres o expresiones. Solo conoce las referencias y su ubicación. Aquí también, no puedes obtener lo que no existe. La expresión o el nombre de la variable no existe.
Filosofía: No puedes hacer una tortilla si no tienes un huevo en primer lugar.
No estoy seguro, pero esto puede deberse a que .Net no sabe si es una clase predefinida o definida por el usuario. Si está predefinido, puede ser nulo (como una cadena que ocupa 2 Bytes) pero si está definido por el usuario, tenemos que crear una instancia para que sepa que este objeto ocupará tanta memoria. Entonces, arroja un error en el tiempo de ejecución.