空引用检查的好习惯是什么?
检查对象上的空引用的最有效方法是什么? 我已经看到了各种代码示例,它们具有不同的检查方式,以便最有效或者被认为是最佳实践使用的方法?
Object.ReferenceEquals(item, null) item == null item != null Object.Equals(item, null)
谢谢
-
Object.ReferenceEquals(item, null)
将引用和equals与item == null
进行比较。 -
Object.Equals(item, null)
比较引用类型的引用和值类型的按位,但在reflection器中它等于(item == null) || ((item != null && null != null) && item.Equals(null))
(item == null) || ((item != null && null != null) && item.Equals(null))
。 -
item != null
代码并不总是等于!(item == null)
,但结果当然应该是相等的。 -
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
它总是应该给出与ReferenceEquals
和Equals
相同的结果(所以不需要额外的代码)。
编辑 :确实可以覆盖==
以给出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 == null
比Object.ReferenceEquals(item, null)
或Object.ReferenceEquals(item, null)
非常非常快 ,但只有当它很重要时(我正在处理某事)在哪里我要微观优化一切!)。
要查看有关实施相等性检查的完整指南,请参阅比较参考类型的两个实例的“最佳实践”是什么?
前2个是有效的。
然而,最后一个不仅执行引用检查,也不应该用于空检查。