Eu gostaria de impedir um processamento adicional em um objeto se ele for nulo.
No código a seguir, verifico se o objeto é nulo por:
if (!data.Equals(null))
e
if (data != null)
No entanto, recebo um NullReferenceException
em dataList.Add(data)
. Se o objeto fosse nulo, ele nunca deveria ter inserido a if
instrução-!
Portanto, estou perguntando se essa é a maneira correta de verificar se um objeto é nulo:
public List<Object> dataList;
public bool AddData(ref Object data)
bool success = false;
try
{
// I've also used "if (data != null)" which hasn't worked either
if (!data.Equals(null))
{
//NullReferenceException occurs here ...
dataList.Add(data);
success = doOtherStuff(data);
}
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
return success;
}
Se esta é a maneira correta de verificar se o objeto é nulo, o que estou fazendo de errado (como posso impedir um processamento adicional no objeto para evitar a NullReferenceException)?
c#
null
nullreferenceexception
desenvolvedor
fonte
fonte
throw e;
versusthrow new Exception(e.ToString());
!= null
em suas verificações nulas..Equals
sempre lançará uma exceção se o objeto for nulo.throw e;
não é muito melhor.throw;
, por outro lado ...e.ToString()
produzirá uma string que inclui não apenas a mensagem de erro, mas também as de todosInnerExceptions
e o rastreamento da pilha. Então essa é uma mensagem de exceção muito pesada. Se você (com razão!) Deseja preservar essas informações e manter onde elas pertencem, use simplesmentethrow;
.Respostas:
Não é
data
issonull
, masdataList
.Você precisa criar um com
Ainda melhor: como é um campo, faça-o
private
. E se não houver nada impedindo você, faça isso tambémreadonly
. Apenas boas práticas.a parte, de lado
A maneira correta de verificar a nulidade é
if(data != null)
. Esse tipo de verificação é onipresente para tipos de referência; atéNullable<T>
substitui o operador de igualdade por ser uma maneira mais conveniente de expressarnullable.HasValue
ao verificar a nulidade.Se você o fizer
if(!data.Equals(null))
, receberá umNullReferenceException
ifdata == null
. O que é meio cômico, já que evitar essa exceção era o objetivo em primeiro lugar.Você também está fazendo isso:
Definitivamente, isso não é bom. Eu posso imaginar que você o coloque lá apenas para poder entrar no depurador enquanto ainda estiver dentro do método; nesse caso, ignore este parágrafo. Caso contrário, não pegue exceções por nada. E se o fizer, repita-as usando apenas
throw;
.fonte
null != data
. Colocar a constante primeiro transforma o erro de digitaçãonull = data
no erro do compilador em vez de uma atribuição não intencional. (Também funciona para==
.)if (data = null)
já é um erro de tempo de compilação, por isso, mesmo que demorasse décadas para chegar lá, não precisamos mais ficar atentos a isso. Até os compiladores C ++ produzirão facilmente um aviso sobre possível atribuição não intencional para esse código.em C #> 7.0 use
if (obj is null)
...Isso ignorará qualquer == ou! = Definido pelo objeto (a menos que você queira usá-lo ...)
Para uso não nulo
if (obj is object)
(ouif (!(obj is null))
)fonte
obj is not null
)if (obj aint null)
:(if (obj is object)
C # 6 tem verificação nula monádica :)
antes:
depois de:
fonte
result = myObject == null ? null : myObject.SomeProperty
e seu exemplo me levou a escreverresult = myObject?.SomeProperty
. Homem!! Isso é sorrateiro. Eu ainda amo a codificação ...Seu dataList é nulo, pois não foi instanciado, a julgar pelo código que você postou.
Experimentar:
}
fonte
[Editado para refletir a dica de @ kelton52]
Maneira mais simples é fazer
object.ReferenceEquals(null, data)
Como
(null==data)
NÃO é garantido que funcione:Produz:
fonte
Não, você deveria estar usando
!=
. Se,data
na verdade, for nulo, seu programa irá travar comNullReferenceException
um resultado da tentativa de chamar oEquals
métodonull
. Perceba também que, se você deseja verificar especificamente a igualdade de referência, deve usar oObject.ReferenceEquals
método como nunca sabe comoEquals
foi implementado.Seu programa está travando porque
dataList
é nulo, pois você nunca o inicializa.fonte
O problema neste caso não
data
é que seja nulo. É quedataList
ele próprio é nulo.No local em que você declara,
dataList
você deve criar um novoList
objeto e atribuí-lo à variável.fonte
Além da resposta de Joseph Ortega , é melhor usar o método de extensão
E use o
IsNull
método para todos os objetos como:fonte
return T == null ? true : false;
e não apenasreturn T == null;
?A partir do C # 8, você pode usar o padrão de propriedade 'vazio' (com correspondência de padrão ) para garantir que um objeto seja não nulo:
Essa abordagem significa " se o objeto faz referência a uma instância de algo " (ou seja, não é nulo).
Você pode pensar nisso como o oposto de:
if (obj is null)...
. que retornará true quando o objeto não fizer referência a uma instância de algo.Para mais informações sobre padrões em C # 8.0, leia aqui .
fonte
A partir do C # 9, você pode fazer
Para uso não nulo
Se você precisar substituir esse comportamento, use
==
e de!=
acordo.fonte
Jeffrey L. Whitledge está certo. Seu próprio objeto `dataList´ é nulo.
Também há outro problema com o seu código: você está usando a palavra-chave ref, o que significa que os dados do argumento não podem ser nulos! O MSDN diz:
Também não é uma boa ideia usar genéricos com o tipo `Objeto '. Os genéricos devem evitar o boxe / desembalagem e também garantir a segurança do tipo. Se você deseja um tipo comum, torne seu método genérico. Finalmente, seu código deve ficar assim:
fonte
Como outros já apontaram, não é,
data
mas é bem prováveldataList
que sejanull
. Além disso...catch
-throw
é um antipadrão que quase sempre me dá vontade de vomitar toda vez que o vejo. Imagine que algo dê errado no fundo de algo quedoOtherStuff()
chama. Tudo o que você recebe de volta é umException
objeto, jogadothrow
na entradaAddData()
. Sem rastreamento de pilha, sem informações de chamada, sem estado, nada para indicar a fonte real do problema, a menos que você entre e alterne seu depurador para interromper a exceção lançada em vez da exceção não tratada. Se você está capturando uma exceção e apenas a reproduzindo de alguma forma , principalmente se o código no bloco try não for trivial, faça um favor a si mesmo (e a seus colegas, presente e futuro) e jogue fora todotry
-catch
bloco . Concedido,throw;
é melhor do que as alternativas, mas você ainda está dando a si mesmo (ou a quem quer que esteja tentando corrigir um bug no código) dores de cabeça completamente desnecessárias. Isso não quer dizer que o try-catch-throw seja necessariamente ruim por si só, desde que você faça algo relevante com o objeto de exceção lançado dentro do bloco catch.Depois, existem os possíveis problemas de captura
Exception
em primeiro lugar, mas isso é outra questão, principalmente porque nesse caso em particular você lança uma exceção.Outra coisa que me parece mais do que um pouco perigosa é que
data
poderia potencialmente alterar valor durante a execução da função, já que você está passando por referência. Portanto, a verificação nula pode passar, mas antes que o código faça algo com o valor, ele é alterado - talvez paranull
. Não tenho certeza se isso é uma preocupação ou não (pode não ser), mas parece que vale a pena prestar atenção.fonte
usar:
Uso condicional:
Atualização (outra maneira) atualizada em 31/08/2017. Obrigado pelo comentário.
fonte
cond ? true : false;
é completamente equivalente a apenascond
. Isso não acrescenta nada.return T == null;
também retorna um booleano!return T == null ? true : false;
apenas usarreturn T == null;
.Sempre que você estiver criando objetos da classe, verifique se o objeto é nulo ou não usando o código abaixo.
Exemplo: object1 é objeto da classe
fonte
Eu apenas segui um método que normalmente seguiríamos no script java. Para converter objeto em string e verifique se eles são nulos.
fonte
Eu fiz mais simples (maneira positiva) e parece funcionar bem.
Como qualquer tipo de "objeto" é pelo menos um objeto
fonte