Con respecto a este mensaje de excepción no controlada de .NET:
Referencia a objeto no establecida como instancia de un objeto.
¿Por qué .NET no muestra qué objeto es null
?
Sé que puedo verificar 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
?
Respuestas:
(Para obtener información sobre el nuevo asistente de excepción en Visual Studio 2017, consulte el final de esta respuesta)
Considere este código:
Esto arrojará un
NullReferenceException
en la segunda línea y querrá saber por qué .NET no le dices
que era nulo cuando se lanzó la excepción.Para entender por qué no obtiene esa información, debe recordar que no es la fuente C # la que se ejecuta, sino IL:
Es el
callvirt
código de operación el que arroja elNullReferenceException
y lo hace cuando el primer argumento en la pila de evaluación es una referencia nula (la que se cargó usandoldloc.0
).Si .NET debería poder decir que
s
fue una referencia nula, debería de alguna manera rastrear que el primer argumento en la pila de evaluación se originó en el formularios
. En este caso, es fácil para nosotros ver que ess
nulo, pero ¿qué pasa si el valor es un valor de retorno de otra llamada de función y no se almacena en ninguna variable? De todos modos, este tipo de información no es lo que desea rastrear en una máquina virtual como la máquina virtual .NET.Para evitar este problema, le sugiero que realice una verificación nula de argumentos en todas las llamadas a métodos públicos (a menos que, por supuesto, permita la referencia nula):
Si se pasa nulo al método, 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 intentará decir qué es nulo cuando
NullReferenceException
se lanza un. Incluso es capaz de brindarle la información requerida cuando es el valor de retorno de un método que es nulo:Tenga en cuenta que esto solo funciona en una compilación DEBUG.
fuente
null
?null
? Tenga en cuenta que el OP no afirma que quiera saber que para las versiones de lanzamiento, las versiones de depuración pueden ser suficientes.null
) con la línea y columna del archivo fuente que devolvió esa referencia de objeto.¿Cómo quiere que se vea el mensaje de error en el siguiente caso?
¡No hay nombres de variables para informar aquí!
fuente
Object reference obtained from AnyObject.GetANullObject() not set to an instance of an object.
como el mensaje de error.Bueno, eso depende de los ingenieros de Microsoft. Pero, obviamente, puede usar un depurador y agregar un reloj para descubrir cuál de ellos tiene un problema.
Sin embargo, la excepción es lo
NullReferenceException
que significa que la referencia no existe . No puede obtener el objeto que no se ha 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!Lo mismo ocurre cuando digo que C # se compila en código .NET IL. El código .NET IL no conoce los nombres o expresiones. Solo conoce referencias y su ubicación. Aquí tampoco se puede 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.
fuente
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, entonces 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á esta cantidad de memoria. Por lo tanto, arroja un error en tiempo de ejecución.
fuente
Buena pregunta. El cuadro de mensaje es casi inútil. Incluso si está enterrado a una milla de profundidad de la definición de referencias, alguna clase o ensamblado o archivo u otra información sería mejor que lo que proporcionan actualmente (lea: 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).
fuente