检查C#中的对象是否为null

dev*_*per 196 c# null nullreferenceexception

我想阻止对象的进一步处理,如果它是null.

在下面的代码中,我通过以下任一方法检查对象是否为null:

if (!data.Equals(null))
Run Code Online (Sandbox Code Playgroud)

if (data != null)
Run Code Online (Sandbox Code Playgroud)

不过,我收到NullReferenceExceptiondataList.Add(data).如果对象为null,则它应该永远不会进入if-statement!

因此,我问这是否是检查对象是否为null的正确方法:

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;
}
Run Code Online (Sandbox Code Playgroud)

如果这是检查对象是否为null的正确方法,那么我做错了什么(如何防止对对象进一步处理以避免NullReferenceException)?

Jon*_*Jon 235

不是data那样null,但是dataList.

你需要创建一个

public List<Object> dataList = new List<Object>();
Run Code Online (Sandbox Code Playgroud)

更好的是:因为它是一个领域,所以要做到private.如果没有什么可以阻止你的话,那就去做吧readonly.只是好习惯.

在旁边

检查无效的正确方法是if(data != null).对于参考类型,这种检查无处不在; 甚至Nullable<T>覆盖等于运算符,以便nullable.HasValue在检查无效时更方便地表达.

如果你这样做,if(!data.Equals(null))你会得到一个NullReferenceExceptionif data == null.这是一种滑稽,因为避免这种异常首先是目标.

你也是这样做的:

catch (Exception e)
{
    throw new Exception(e.ToString());
}
Run Code Online (Sandbox Code Playgroud)

这绝对不是好事.我可以想象你把它放在那里只是为了你可以在方法内部进入调试器,在这种情况下忽略这一段.否则,不要抓住异常.如果你这样做,只需使用它们重新抛出它们throw;.

  • 为此,我也见过*Object.ReferenceEquals(obj,null)*.这是为了避免平等优先吗? (5认同)
  • @jpmc26:在C#中,if(data = null)`已经是一个编译时错误,所以即使花了几十年到达那里我们也不需要再注意了.即使是C++编译器也会轻易产生关于该代码可能无意识分配的警告. (5认同)
  • 我更喜欢`null!= data`.将常量放在第一位会使得骨头错误"null = data"变成编译器错误,而不是无意的赋值.(也适用于`==`.) (4认同)
  • @LucaPiccioni我用它来防止使用泛型时的值类型抱怨:http://www.geekality.net/2009/11/13/generics-and-checking-for-null/ (2认同)

Jow*_*wen 53

C#6有monadic null检查 :)

之前:

if (points != null) {
    var next = points.FirstOrDefault();
    if (next != null && next.X != null) return next.X;
}   
return -1;
Run Code Online (Sandbox Code Playgroud)

后:

var bestValue = points?.FirstOrDefault()?.X ?? -1;
Run Code Online (Sandbox Code Playgroud)

  • 因为"评论只能编辑5分钟"?什么?无论如何...当我到达它时......我来到这里是为了寻找更好的语法来表达`result = myObject == null?null:myObject.SomeProperty`和你的例子让我写了`result = myObject?.SomeProperty`.人!!那是偷偷摸摸的.我还是喜欢编码...... (7认同)

kof*_*fus 44

在C#7中最好的是

if (obj is null) ...

这将忽略对象定义的任何==或!=(除非您当然要使用它们......)

如果不相等,你可以if (obj is object)(丑陋)

  • 希望他们实现`if(obj aint null)`:( (10认同)
  • @OrnKristjansson 因为 != 和 == 可以被覆盖。 (4认同)
  • 我想知道是否有“不为空”?(python 会说 `obj is not null`) (2认同)
  • if(!(obj为null)) (2认同)
  • 对于不为null的存在`if(obj是object)` (2认同)
  • 我怀念 VB.NET 中的“IsNot”运算符(以及布尔运算符“And”和“Or”——比 &amp;&amp; 和 || 更具可读性) (2认同)
  • 对于阅读这些评论的任何人,请注意,很多 vb 开发人员似乎没有意识到“And”和“Or”不等于“&amp;&amp;”和“||”;后者短路,前者不短路。语义等价物是“AndAlso”/“OrElse” (2认同)

glo*_*rob 27

您的dataList为null,因为它尚未实例化,根据您发布的代码判断.

尝试:

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;
Run Code Online (Sandbox Code Playgroud)

}

  • 但尝试在null上执行.Equals会抛出异常.应该做!= null (7认同)
  • 另外,只需要添加,如果data为null,则不会崩溃,可以将null添加到List <Object>. (3认同)

gat*_*ich 18

[编辑反映@ kelton52的暗示]

最简单的方法就是做 object.ReferenceEquals(null, data)

由于(null==data)不保证工作:

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));
}
Run Code Online (Sandbox Code Playgroud)

生产:

将''与'Nully'进行比较

真正

  • 实际上我只是尝试过这个,并且评论“隐含的优势是它忽略了数据类中可能存在的任何覆盖,例如“运算符!=”。似乎不成立。 (2认同)

chi*_*s0v 15

C# 9 开始,你可以做

if (obj is null) { ... }
Run Code Online (Sandbox Code Playgroud)

对于非空使用

if (obj is not null) { ... }
Run Code Online (Sandbox Code Playgroud)

如果您需要覆盖此行为==,请!=相应地使用。


Ed *_* S. 9

不,你应该使用!=.如果data实际上为null,那么您的程序将NullReferenceException因尝试调用该Equals方法而崩溃null.还要意识到,如果您特别想要检查引用相等性,那么您应该使用该Object.ReferenceEquals方法,因为您永远不知道如何Equals实现.

您的程序崩溃,因为dataList您从未初始化它是null.


Jef*_*dge 6

在这种情况下的问题不是datanull.它dataList本身就是空的.

在您声明的位置,您dataList应该创建一个新List对象并将其分配给变量.

List<object> dataList = new List<object>();
Run Code Online (Sandbox Code Playgroud)


Yga*_*bel 6

使用 c#9 (2020),您现在可以使用以下代码检查参数是否为空:

if (name is null) { }

if (name is not null) { }
Run Code Online (Sandbox Code Playgroud)

您可以在此处获得更多信息


Ali*_*Ali 5

除了@Jose Ortega答案外,它更好地用于扩展方法

 public static bool IsNull(this object T)
     {
        return T == null;
     } 
Run Code Online (Sandbox Code Playgroud)

并对IsNull所有对象使用方法,例如:

object foo = new object(); //or any object from any class
if (foo.IsNull())
   {
     // blah blah //
   }
Run Code Online (Sandbox Code Playgroud)

  • 我不确定我是否同意。在对象上调用方法来检查它是否为空看起来很奇怪。在不知道它是一个扩展方法的情况下,您会认为它会抛出一个空引用异常。 (2认同)

Dar*_*ane 5

C# 8 开始,您可以使用“空”属性模式(使用模式匹配)来确保对象不为空:

if (obj is { })
{
    // 'obj' is not null here
}
Run Code Online (Sandbox Code Playgroud)

这种方法意味着“如果对象引用某物的实例”(即它不为空)。

你可以把这看作是:的反面if (obj is null)...。当对象不引用某物的实例时,它将返回 true。

有关 C# 8.0 模式的更多信息,请阅读此处