检查对象上的空引用的最有效方法是什么?我见过各种代码示例,它们有不同的方法来检查以下哪种方法最有效,或者被认为是最佳使用的方法?
Object.ReferenceEquals(item, null)
item == null
item != null
Object.Equals(item, null)
感谢
答案 0 :(得分:8)
Object.ReferenceEquals(item, null)
将引用和等于item == null
。Object.Equals(item, null)
比较引用类型的引用和值类型的按位,但在反射器中它等于(item == null) || ((item != null && null != null) && item.Equals(null))
。item != null
代码并不总是等于!(item == null)
,但结果当然应该相等。item == null
代码不等于null == item
,类似于typeof(item).Equals(object)
和object.Equals(typeof(item))
方法调用。它有所不同,因为您可以覆盖!=
,==
,Equals
。
使用已知实现的方法,null == item
更适合编码,但更难阅读。
Object.ReferenceEquals(null, item)
可能更快或更快。
P.S。也使用string.IsNullOrEmpty(item)
答案 1 :(得分:5)
为了与null
进行比较,我始终使用==
或!=
,因为对于null
,它应始终提供与ReferenceEquals
相同的结果,无论如何Equals
(所以不需要额外的代码)。
修改:==
确实可以覆盖null
以便为true
(即==
)提供错误的结果,但这意味着覆盖错误。为了使代码可读,我会坚持使用!=
和{{1}}。
答案 2 :(得分:3)
ReferenceEquals
相当于(object)o1==(object)o2
。如果等于运算符过载,它可能比o1==o2
更快。 Object.Equals
可能有点慢。
==
和!=
之间的差异不是表现,而是程序的外观。如果==
和!=
运算符过载,它们可能会慢一些。
但我认为它们之间的性能差异根本不重要。我会选择最容易阅读的那个。这通常是==
或!=
。
如果我抛出异常,我通常会使用==
,如下所示:
if(o == null)
throw new ...;
如果null
导致无操作,则通常!=
是合适的
if(x != null)
{
...
}
答案 3 :(得分:3)
作为额外的,不要忘记.NET 4.0中的代码合约!
System.Diagnostics.Contracts.Contract.Requires(item != null);
这不仅好看而且清晰,但允许编译时间检查。请参阅msdn。中的Code Contracts
答案 4 :(得分:3)
从C#7.0起,您可以使用:
item is null
应该是最简单,最简单的方式。它与ReferenceEquals
检查相同。
<强> 1)强>
Object.ReferenceEquals(item, null)
这是一个好方法。不像我喜欢的那样简洁,但仍然很好并且完全告诉你意图。
<强> 2)强>
item == null
item != null
如果您确定==
并且随后!=
正确重载,则此处(最优雅)没有任何问题。它易于编写(重载)坏的等式运算符(并且经常完成)。但真正的麻烦在于你试图在类中重载==
运算符(比如说值语义)。 您无法在==
重载类since that will cause an infinite recursion 的函数内使用==
进行空值检查。为了拥有一致的风格,我依靠别的东西。
第3)强>
Object.Equals(item, null)
同样它在内部做了一个ReferenceEquals
所以没有多大意义,但如果它在语义上对你更有意义,那就去吧。
<强> 4)强>
我的方法是做
(object)item == null
我依赖于object
自己的等式运算符,它不会出错。不太可读,所以我只是包装自定义扩展方法和重载:
public static bool IsNull<T>(this T obj) where T : class
{
return (object)obj == null;
}
public static bool IsNull<T>(this T? obj) where T : struct
{
return !obj.HasValue;
}
这更有意义,因为我需要经常检查DBNull
。所以现在我有一个一贯的风格!
public static bool IsNull<T>(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
very very very slightly faster than Object.ReferenceEquals(item, null)
或object.Equals(,)
就此问题,但只有在重要的时候(我正在研究我要微观优化一切的事情) !)。
要查看有关实施平等检查的完整指南,请参阅What is "Best Practice" For Comparing Two Instances of a Reference Type?
答案 5 :(得分:2)
我总是使用
item != null
但这比
更难阅读item == null
Object.ReferenceEquals用于检查两个对象是否是同一个实例。
答案 6 :(得分:-1)
前2个是有效的。
但是最后一个不仅进行了引用检查,而且不应该用于空检查。