在C#中检查对象是否为空

如果对象为空,我想阻止进一步的处理。

在下面的代码中,我检查对象是否为null:

if (!data.Equals(null)) 

 if (data != null) 

但是,我收到一个NullReferenceExceptiondataList.Add(data) 。 如果对象为null,则应该永远不会inputif -statement!

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

 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; } 

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

这不是null data ,而是dataList

你需要创build一个

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

更好:因为它是一个领域,所以它是private 。 如果没有什么可以阻止你,那么只能readonly 。 只是好的做法。

在旁边

检查无效的正确方法是if(data != null) 。 这种检查是无处不在的参考types; 即使Nullable<T>也会覆盖相等运算符,以便在检查无效性时更方便地expressionnullable.HasValue

如果你这样做if(!data.Equals(null))那么你会得到一个NullReferenceException如果data == null 。 这是一种滑稽的,因为避免这个例外是首要的目标。

你也是这样做的:

 catch (Exception e) { throw new Exception(e.ToString()); } 

这绝对不好。 我可以想象,你把它放在那里,这样你就可以在debugging器内部进入方法,在这种情况下忽略这个段落。 否则,不要一无所获。 如果你这样做,用抛出的方式重新throw;

你的dataList是空的,因为它没有被实例化,根据你发布的代码来判断。

尝试:

 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; 

}

C#6有monadic null检查 🙂

之前:

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

后:

 var bestValue = points?.FirstOrDefault()?.X ?? -1; 

[编辑反映@ 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)); } 

生产:

比较''和'Nully'

真正

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

你的程序崩溃,因为你永远不会初始化dataList为空。

这种情况下的问题不是data是空的。 这是dataList本身是空的。

在你声明dataList的地方,你应该创build一个新的List对象并将其分配给variables。

 List<object> dataList = new List<object>(); 
  public static bool isnull(object T) { return T == null ? true : false; } 

使用:

 isnull(object.check.it) 

有条件使用:

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

更新(另一种方式)更新08/31/2017。 感谢您的评论。

 public static bool isnull(object T) { return T ? true : false; } 

Jeffrey L Whitledge是对的。 你的`dataList'-Object本身是空的。

你的代码还有另一个问题:你正在使用ref-keyword,这意味着参数数据不能为空! MSDN说:

传递给ref参数的参数必须先被初始化。 这与out不同,它们的参数在传递之前不必被显式初始化

使用types为“Object”的generics也不是一个好主意。 generics应避免拳击/拆箱,并确保types安全。 如果你想要一个普通的types使你的方法是通用的。 最后你的代码应该是这样的:

 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) { //... } } 

正如其他人已经指出,这不是data ,而是可能dataListnull 。 在此之上…

catchthrow是一个反模式,几乎总是让我每次看到它时都想吐出来。 想象一下,在其他东西doOtherStuff()调用的东西深层出了doOtherStuff() 。 你所得到的是一个Exception对象,抛出在AddData() throw 。 没有堆栈跟踪,没有调用信息,没有状态,根本没有什么可以指出问题的真正根源,除非你进入并切换你的debugging器来抛出exception抛出,而不是exception处理。 如果你正在捕捉一个exception,并以任何方式重新抛出exception,特别是如果try块中的代码是非常平凡的,那么请自己(和你的同事,现在和未来)做一个忙,并抛出所有的trycatch块。 当然, throw; 比替代scheme更好,但是你仍然给自己(或者其他任何试图修正代码中的错误的人)完全不必要的头痛。 这并不是说try-catch-throw本身就是邪恶的,只要你在catch块中抛出exception对象

那么首先会遇到捕获Exception的潜在问题,但这是另一个问题,特别是在这种情况下,您会抛出exception。

另一件让我觉得不止一点危险的事情是data可能在函数执行期间改变值,因为你是通过引用传递的。 所以,空检查可能会通过,但在代码做任何事情的价值之前,它已经改变 – 也许是null 。 我不积极,如果这是一个问题(可能不是),但它似乎值得注意。

除了@Jose Ortega的答案,它更好的使用扩展方法

  public static bool IsNull(this object T) { return T == null ? true : false; } 

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

 object foo = new object();//or any object from any class if (foo.IsNull()) { ///bla bla }