Em relação a esta mensagem de exceção não tratada do .NET:
Referência de objeto não definida para uma instância de um objeto.
Por que o .NET não mostra qual objeto é null
?
Sei que posso verificar null
e resolver o erro. No entanto, por que o .NET não ajuda a apontar qual objeto tem uma referência nula e qual expressão acionou o NullReferenceException
?
Respostas:
(Para obter informações sobre o novo auxiliar de exceção no Visual Studio 2017, consulte o final desta resposta)
Considere este código:
Isso lançará um
NullReferenceException
na segunda linha e você deseja saber por que o .NET não informas
que era nulo quando a exceção foi lançada.Para entender por que você não consegue essa informação, você deve se lembrar de que não é a fonte C # que executa, mas IL:
É o
callvirt
opcode que lança oNullReferenceException
e faz isso quando o primeiro argumento na pilha de avaliação é uma referência nula (aquela que foi carregada usandoldloc.0
).Se o .NET for capaz de dizer que se trata de
s
uma referência nula, ele deve, de alguma forma, rastrear que o primeiro argumento na pilha de avaliação se originous
. Nesse caso, é fácil para nós ver que és
nulo, mas e se o valor for um valor de retorno de outra chamada de função e não estiver armazenado em nenhuma variável? De qualquer forma, esse tipo de informação não é o que você deseja acompanhar em uma máquina virtual como a máquina virtual .NET.Para evitar esse problema, sugiro que você execute a verificação de argumento nulo em todas as chamadas de método público (a menos, é claro, que você permita a referência nula):
Se null for passado para o método, você obterá uma exceção que descreve precisamente qual é o problema (isto
s
é, null).Quatro anos depois, o Visual Studio 2017 agora tem um novo auxiliar de exceção que tentará dizer o que é nulo quando um
NullReferenceException
é lançado. Ele pode até mesmo fornecer as informações necessárias quando for o valor de retorno de um método nulo:Observe que isso só funciona em um build DEBUG.
fonte
null
.null
- observe que o OP não afirma que quer saber que, para compilações de lançamento, também as compilações de depuração podem ser suficientes.null
) com a linha e coluna do arquivo de origem que retornou essa referência de objeto.Como você deseja que a mensagem de erro seja exibida no seguinte caso?
Não há nomes de variáveis para relatar aqui!
fonte
Object reference obtained from AnyObject.GetANullObject() not set to an instance of an object.
a mensagem de erro.Bem, cabe aos engenheiros da Microsoft responder. Mas obviamente você pode usar um depurador e adicionar watch para descobrir qual deles tem um problema.
No entanto, a exceção é o
NullReferenceException
que significa que a referência não existe . Você não pode obter o objeto que não foi criado.but why .NET don't tell us which object is null?
Porque ele não sabe qual objeto é nulo. O objeto simplesmente não existe!O mesmo é o caso quando digo, C # é compilado para código .NET IL. O código .NET IL não conhece os nomes ou expressões. Ele só conhece referências e sua localização. Aqui também, você não pode obter o que não existe. A expressão ou o nome da variável não existe.
Filosofia: Você não pode fazer uma omelete se não tiver um ovo.
fonte
Não tenho certeza, mas pode ser porque .Net não sabe se é uma classe predefinida ou definida pelo usuário. Se for predefinido, pode ser nulo (como uma string que ocupa 2 bytes), mas se for definido pelo usuário, temos que criar uma instância dele para que saiba que esse objeto ocupará essa quantidade de memória. Portanto, ele lança um erro em tempo de execução.
fonte
Boa pergunta. A caixa de mensagem é quase inútil. Mesmo que esteja enterrado a uma milha de profundidade da definição de referências, alguma classe ou montagem ou arquivo ou outra informação seria melhor do que o que eles fornecem atualmente (leia-se: melhor do que nada).
Sua melhor opção é executá-lo no depurador com informações de depuração, e seu IDE quebrará na linha problemática (demonstrando claramente que informações úteis estão de fato disponíveis).
fonte