C# - Object reference not set to an instance of an object
Hoje veremos como tratar a exceção : 'Object reference not set to an instance of an object' |
Por
exemplo, considere o seguinte código:
string nome = null;
int length = nome.Length;
|
Nesse caso, a exceção "Object reference not set to an instance of an object" será lançada porque a variável nome não foi inicializada e, portanto, não aponta para nenhum objeto válido. Quando o método Length é chamado, ocorre uma tentativa de acessar um membro em um objeto que não existe, o que leva à exceção.
Para evitar essa exceção, é importante garantir que todas as variáveis que representam objetos sejam inicializadas corretamente antes de serem usadas em qualquer operação. Também é importante verificar se uma variável que pode ser null antes de tentar acessar um membro nela.
Uma das maneiras mais simples de verificar se uma variável é null é usar o operador de coalescência nula ?? :
string nome = null;
int length = (nome ?? "").Length;
|
Nesse caso, o operador ?? verifica se nome é null e, se for, retorna uma string vazia (""). Isso garante que a chamada ao método Length não falhe, mesmo se a variável s for null.
Esta exceção é uma das exceções mais comuns em C# e pode ocorrer em vários cenários, incluindo:
Vejamos a seguir 3 causas principais da ocorrência desta exceção.
Causa nº 1: Acessando uma variáel que não foi inicializada
Ao tentar acessar uma variável que não foi inicializada, a exceção "Object reference not set to an instance of an object" será lançada.
Isso ocorre porque a variável não possui um valor atribuído a ela e, portanto, não aponta para nenhum objeto válido na memória.
Quando uma variável é declarada sem ser inicializada, seu valor é definido como null por padrão. Se um código tentar acessar uma variável que é null, uma exceção será lançada. Por exemplo:
string
mensagem; Console.WriteLine(mensagem); |
Nesse caso, a variável mensagem é declarada, mas não é inicializada com um valor. Quando o método Console.WriteLine tenta acessar a variável, ocorre uma tentativa de acessar um membro em um objeto que não existe, o que leva à exceção "Object reference not set to an instance of an object".
Para evitar essa exceção, é importante inicializar todas as variáveis com valores apropriados antes de usá-las em qualquer operação. Isso pode ser feito atribuindo um valor à variável no momento da declaração ou em algum ponto posterior do código antes de usá-la :
string
mensagem = "Olá..."; Console.WriteLine(mensagem); |
Agora mensagem é inicializada com um valor pertinente evitando a exceção.
Causa nº 2: O objeto está definido como nulo
Outra causa desta exceção é quando um objeto é definido como nulo. O
Null é um valor
especial que representa a ausência de um valor e pode ser atribuído a uma
variável para indicar que ela não se refere a nenhum objeto no momento. Quando
um objeto é definido como nulo, qualquer tentativa de acessar suas propriedades
ou métodos resultará no mesmo erro.
string
nome = null; int tamanho = nome.Length; |
No
código acima, a variável nome é definida como nula e, quando a propriedade
Length do objeto string é acessada, o erro é
lançado. Para corrigir esse erro, a variável de texto deve ser inicializada com
um valor de string válido antes que suas propriedades ou métodos sejam
acessados.
Além de inicializar variáveis, podemos usar técnicas de programação defensiva
para evitar este erro. A programação defensiva envolve a escrita de código que
antecipa e manipula possíveis erros, como variáveis nulas ou não
inicializadas.
string
nome = null; if (nome != null) { int tamanho = nome.Length; } |
A instrução if no código de exemplo acima verifica se a variável nome é nula antes de acessar sua propriedade Length. Isso garante que o código não lançará a exceção.
Temos as seguintes alternativas ao código acima que vão atuar da mesma forma:
a-)
string
nome = null; if (nome is not null) { int tamanho = nome.Length; } |
b-)
string
nome = null; nome ??= "sem nome";int tamanho = nome.Length; |
c-)
string
nome = null; if (!string.IsNullOrEmpty(nome)){ int tamanho = nome.Length; } |
Causa nº 3: Quando FirstOrDefault() ou SingleOrDefault()
retorna null
Esta é provavelmente uma das causas mais frequentes que causam essa exceção.
Isso acontecerá quando uma coleção não tiver um objeto que corresponda aos
critérios do filtro. Qualquer tentativa de acessar as propriedades do objeto
resultará no mesmo erro.
var
usuario = _context.Usuarios.FirstOrDefault(x => x.Nome ==
"Maria"); var nomeCompleto = usuario.Nome + " " + usuario.Sobrenome; |
No
código acima, a exceção vai ocorrer se nenhum usuário com nome "Maria"
for encontrado no banco de dados, pois o valor atribuído a variável usuário será
null.
Existem várias maneiras de resolver esse problema. Primeiro, podemos usar
técnicas de programação defensiva para evitar o erro:
var
usuario = _context.Usuarios.FirstOrDefault(x => x.Nome ==
"Maria"); var nomeCompleto = "";if (usuario != null)nomeCompleto= usuario.Nome + " " + usuario.Sobrenome; |
Em segundo lugar, também podemos usar o operador condicional nulo ? . Este operador nos permite acessar as propriedades ou métodos de um objeto somente se o objeto não for nulo, sem lançar uma exceção se o objeto for nulo.
var
usuario = _context.Usuarios.FirstOrDefault(x => x.Nome ==
"Maria"); var nomeCompleto = usuario?.Nome + " " + usuario?.Sobrenome; |
Em terceiro lugar, também podemos lançar uma exceção customizada e deixar o chamador do método ou o manipulador de erro global lidar com a exceção:
var
usuario = _context.Usuarios.FirstOrDefault(x => x.Nome ==
"Maria"); if (usuario is null){ throw new NotFoundException("Usuário não encontrado."); } public class NotFoundException: Exception{ public NotFoundException(string mensagem) : base(mensagem) { } } |
Desta forma, esta exception pode ser evitada inicializando corretamente as
variáveis, usando técnicas de programação defensiva, usando operadores
condicionais nulos e coalescentes nulos ou lançando uma exceção personalizada
que o aplicativo manipulará.
E estamos
conversados ...
"Eu sou a videira, vós as varas; quem está em mim, e eu nele,
esse dá muito fruto; porque sem mim nada podeis fazer."
João 15:5
Referências:
LINQ - Gerando um Produto Cartesiano - Macoratti
C# - Salvando e Lendo informações em um arquivo XML - Macoratti