Verificar se um objecto é nulo em C#

gostaria de impedir o processamento de um objecto se este for nulo.

no seguinte código, verifico se o objecto é nulo por:

if (!data.Equals(null))

e

if (data != null)
No entanto, recebo um NullReferenceException em dataList.Add(data). Se o objeto foi nulo, ele nunca deveria ter sequer entrado na declaração if!

Assim, estou a perguntar se esta é a maneira correcta de verificar se um objecto é 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 forma correcta de verificar se o objecto é nulo, o que estou a fazer? errado (Como posso evitar o processamento adicional no objeto para evitar a Isenção de realimentação)?

Author: Peter Mortensen, 2011-06-21

12 answers

Não é data isso é null, mas dataList.

Você precisa criar um com

public List<Object> dataList = new List<Object>();

Ainda melhor: já que é um campo, faça-o private. E se não há nada que te impeça, fá-lo também. É só um bom treino.

De lado.

A forma correcta de verificar a nulidade é if(data != null). Este tipo de controlo é omnipresente para tipos de referência; mesmo Nullable<T> sobrepõe-se ao operador da igualdade para ser uma forma mais conveniente de expressar nullable.HasValue ao verificar nulidade.

Se o fizeres {[10] } então terás um NullReferenceException se data == null. O que é um pouco cómico, já que evitar esta excepção era o objectivo em primeiro lugar.

Também estás a fazer isto:

catch (Exception e)
{
    throw new Exception(e.ToString());
}
Isto não é nada bom. Eu posso imaginar que você colocá-lo lá apenas para que você possa quebrar no depurador enquanto ainda dentro do método, caso em que ignorar este parágrafo. Caso contrário, não apanhes excepções por nada. E se o fizer, repense-os usando apenas throw;.
 205
Author: Jon, 2011-06-20 23:34:27

C# 6 tem verificação monádica nula :)

Antes de:

if (points != null) {
    var next = points.FirstOrDefault();
    if (next != null && next.X != null) return next.X;
}   
return -1;

Depois de:

var bestValue = points?.FirstOrDefault()?.X ?? -1;
 38
Author: Jowen, 2015-09-28 08:10:14

O seu dataList é nulo porque não foi instanciado, a julgar pelo código que publicou.

Tenta:

public List<Object> dataList = new List<Object>();
public  bool AddData(ref Object data)
bool success = false;
try
{
    if (!data.Equals(null))   // I've also used if(data != null) which hasn't worked either
    {
       dataList.Add(data);                      //NullReferenceException occurs here
       success = doOtherStuff(data);
    }
}
catch (Exception e)
{
    throw new Exception(e.ToString());
}
return success;

}

 26
Author: glosrob, 2011-06-20 22:04:50

[editado para reflectir a sugestão de @kelton52]

A maneira mais simples é fazer object.ReferenceEquals(null, data)

Uma vez que {[2] } não é garantido que funcione:

class Nully
{
    public static bool operator ==(Nully n, object o)
    {
        Console.WriteLine("Comparing '" + n + "' with '" + o + "'");
        return true;
    }
    public static bool operator !=(Nully n, object o) { return !(n==o); }
}
void Main()
{
    var data = new Nully();
    Console.WriteLine(null == data);
    Console.WriteLine(object.ReferenceEquals(null, data));
}

Produz:

Comparando " com 'Nully'

Verdadeiro

Falso

 16
Author: gatopeich, 2012-10-25 08:52:14

Não, devias estar a usar {[[0]}. Se data for realmente nulo, então o seu programa irá simplesmente estoirar com um NullReferenceException como resultado de tentar chamar o método Equals em null. Perceba também que, se você quiser verificar especificamente a igualdade de referência, você deve usar o método Object.ReferenceEquals Como você nunca sabe como Equals foi implementado.

O teu programa está a falhar porque dataList é nulo porque nunca o inicializas.

 9
Author: Ed S., 2011-06-20 21:51:24

O problema neste caso não é que data seja nulo. É que dataList em si é nulo.

No local onde declara dataList deve criar um novo objecto List e atribuí - lo à variável.

List<object> dataList = new List<object>();
 6
Author: Jeffrey L Whitledge, 2011-06-20 21:42:19

Em C # 7 o melhor é

if (obj is null) ...

Isto vai ignorar qualquer == or != definido pelo objeto (a menos, claro, que você queira usá-los ...)

Pois não podes if (!(obj is null)) (feio)

 6
Author: kofifus, 2018-08-22 00:27:44

Além de @Jose Ortega resposta, seu melhor uso método de extensão

 public static bool IsNull(this object T)
     {
        return T == null;
     } 

E usar IsNull método para todos os objectos como:

object foo = new object(); //or any object from any class
if (foo.IsNull())
   {
     // blah blah //
   }
 4
Author: combo_ci, 2018-03-28 19:31:32
O Jeffrey l Whitledge tem razão. O teu próprio objecto datalista é nulo.

Existe também outro problema com o seu código: está a usar a palavra-chave ref, o que significa que os dados do argumento não podem ser nulos! O MSDN diz:

Um argumento passado para um parâmetro ref deve ser inicializado primeiro. Isto difere de fora, cujos argumentos não precisam ser iniciados explicitamente antes de serem passados

Também não é uma boa ideia usar genéricos com o tipo `Objecto´. Os genéricos devem evitar o boxe / desligamento e também garantir a segurança do tipo. Se você quer um tipo comum faça seu método genérico. Finalmente o seu código deve ser assim:

public class Foo<T> where T : MyTypeOrInterface {

      public List<T> dataList = new List<T>();

      public bool AddData(ref T data) {
        bool success = false;
        try {
          dataList.Add(data);                   
          success = doOtherStuff(data);
        } catch (Exception e) {
          throw new Exception(e.ToString());
        }
        return success;
      }

      private bool doOtherStuff(T data) {
        //...
      }
    }
 2
Author: DiableNoir, 2011-06-21 08:51:07

Como outros já salientaram, não é {[[0]} mas muito provável dataList que seja null. Além disso...

catch-throw é um antipattern que quase sempre me dá vontade de vomitar sempre que o vejo. Imagine que algo corre mal profundamente em algo que doOtherStuff() chama. Tudo o que tens de volta é um objecto, atirado ao throw em AddData(). Nenhum traço de pilha, nenhuma informação de chamada, nenhum Estado, nada para indicar a verdadeira fonte do problema, a menos que você vá entre e mude o seu depurador para quebrar a excepção lançada em vez de a abrir. Se você está pegando uma exceção e apenas re-jogando-a de qualquer forma, particularmente se o código no bloco de tentativa é de alguma forma não trivial, faça a si mesmo (e seus colegas, presente e futuro) um favor e jogue fora todo o bloco de teste try-catch block. Concedido, throw; é melhor do que as alternativas, mas você ainda está dando a si mesmo (ou quem quer que esteja tentando corrigir um bug no código) completamente dores de cabeça desnecessárias. Isto não quer dizer que tentar atirar seja necessariamente mau por si só, desde que você faça algo relevante com o objeto de exceção que foi jogado dentro do bloco de captura.

Então há os problemas potenciais de apanhar, mas isso é outra questão, especialmente porque neste caso em particular você abre uma excepção. Outra coisa que me parece mais do que um pouco perigosa é que poderia potencialmente alterar o valor durante a execução da função, uma vez que você está passando por referência. Então a verificação nula pode passar, mas antes que o código comece a fazer qualquer coisa com o valor, ele mudou-talvez para null. Eu não sou positivo se esta é uma preocupação ou não (pode não ser), mas parece que vale a pena olhar para fora.
 2
Author: Michael Kjörling, 2011-06-21 12:12:16
  public static bool isnull(object T)
  {
      return T == null ? true : false;
  }

Utilizar:

isnull(object.check.it)

Uso condicional:

isnull(object.check.it) ? DoWhenItsTrue : DoWhenItsFalse;

Actualização (de outra forma) actualizada 08/31/2017. Obrigado pelo comentário.

public static bool isnull(object T)
{
    return T ? true : false;
}
 2
Author: Jose Ortega, 2017-08-31 17:19:07

Sempre que estiver a criar objectos de classe, terá de verificar se o objecto é nulo ou não usando o código abaixo.

Exemplo: o objectivo 1 é objecto da classe
void myFunction(object1)
{
  if(object1!=null)
  {
     object1.value1 //If we miss the null check then here we get the Null Reference exception
  }
}
 1
Author: user3483639, 2018-04-29 18:55:02