空引用检查的好习惯是什么?

检查对象上的空引用的最有效方法是什么? 我已经看到了各种代码示例,它们具有不同的检查方式,以便最有效或者被认为是最佳实践使用的方法?

Object.ReferenceEquals(item, null) item == null item != null Object.Equals(item, null) 

谢谢

  1. Object.ReferenceEquals(item, null)将引用和equals与item == null进行比较。
  2. Object.Equals(item, null)比较引用类型的引用和值类型的按位,但在reflection器中它等于(item == null) || ((item != null && null != null) && item.Equals(null)) (item == null) || ((item != null && null != null) && item.Equals(null))
  3. item != null代码并不总是等于!(item == null) ,但结果当然应该是相等的。
  4. item == null code不等于null == item ,它类似于typeof(item).Equals(object)typeof(item).Equals(object) object.Equals(typeof(item))方法调用。

它有所不同,因为你可以覆盖!===Equals 。 使用已知实现的方法, null == item更适合编码,但更难阅读。 Object.ReferenceEquals(null, item)可能更快或更快。

PS也使用string.IsNullOrEmpty(item)

为了比较null ,我使用==!= always,因为对于null它总是应该给出与ReferenceEqualsEquals相同的结果(所以不需要额外的代码)。

编辑 :确实可以覆盖==以给出null的错误结果(即, true ),但这意味着覆盖是错误的。 为了使代码可读,我会坚持使用==!=

另外,不要忘记.NET 4.0中的代码合约!

 System.Diagnostics.Contracts.Contract.Requires(item != null); 

这不仅好看而且清晰,但允许编译时间检查。 请参阅msdn中的代码合同 。

ReferenceEquals等价于(object)o1==(object)o2 。 如果等于运算符过载,它可能比o1==o2更快。 Object.Equals可能有点慢。

==!=之间的区别不是性能,而是程序的外观。 如果==!=运算符过载,它们可能会慢一些。

但我认为它们之间的性能差异根本不重要。 我会选择最容易阅读的那个。 这通常是==!=

如果我抛出exception,我通常使用==如:

 if(o == null) throw new ...; 

如果null导致no-op,那么通常!=是合适的

 if(x != null) { ... } 

我总是用

 item != null 

但这比阅读起来更难

 item == null 

Object.ReferenceEquals用于检查两个对象是否是同一个实例。

1)

 Object.ReferenceEquals(item, null) 

这是一个好方法。 不像我想的那样简洁,但仍然很好并且完全告诉你意图。

2)

 item == null item != null 

如果您确定==并且随后!=正确重载,那么这是最优雅的 (没有任何问题)。 它易于编写(重载)坏的等式运算符(并且经常完成)。 但真正的麻烦在于你在一个类中尝试重载==运算符(比如说值语义)。 你不能使用==进行null检查内部==重载类的函数, 因为这将导致无限递归 。 为了拥有一致的风格,我依靠别的东西。

3)

 Object.Equals(item, null) 

同样它在内部做了一个ReferenceEquals所以没有多少意义,但如果它在语义上对你更有意义,那就去吧。

4)

我的方法是做

 (object)item == null 

我依赖于object自己的等式运算符,它不会出错。 不太可读,所以我只是包装自定义扩展方法和重载:

 public static bool IsNull(this T obj) where T : class { return (object)obj == null; } public static bool IsNull(this T? obj) where T : struct { return !obj.HasValue; } 

它更有意义,因为我需要经常检查DBNull 。 所以现在我有一个一贯的风格!

 public static bool IsNull(this T obj) where T : class { return (object)obj == null || obj == DBNull.Value; } 

(不要取消(object)强制转换,因为这样可以防止超载时的无限递归==如前所述)

此外,约束会阻止值类型的IsNull 。 现在它像打电话一样甜蜜

 object obj = new object(); Guid? guid = null; bool b = obj.IsNull(); // false b = guid.IsNull(); // true 2.IsNull(); // error 

我也发现(object)item == nullObject.ReferenceEquals(item, null)Object.ReferenceEquals(item, null)非常非常快 ,但只有当它很重要时(我正在处理某事)在哪里我要微观优化一切!)。

要查看有关实施相等性检查的完整指南,请参阅比较参考类型的两个实例的“最佳实践”是什么?

前2个是有效的。

然而,最后一个不仅执行引用检查,也不应该用于空检查。