在C#中检查对象是否为空
如果对象为空,我想阻止进一步的处理。
在下面的代码中,我检查对象是否为null:
if (!data.Equals(null))
和
if (data != null)
但是,我收到一个NullReferenceException
在dataList.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
,而是可能dataList
是null
。 在此之上…
catch
– throw
是一个反模式,几乎总是让我每次看到它时都想吐出来。 想象一下,在其他东西doOtherStuff()
调用的东西深层出了doOtherStuff()
。 你所得到的是一个Exception
对象,抛出在AddData()
throw
。 没有堆栈跟踪,没有调用信息,没有状态,根本没有什么可以指出问题的真正根源,除非你进入并切换你的debugging器来抛出exception抛出,而不是exception处理。 如果你正在捕捉一个exception,并以任何方式重新抛出exception,特别是如果try块中的代码是非常平凡的,那么请自己(和你的同事,现在和未来)做一个忙,并抛出所有的try
– catch
块。 当然, 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 }