C# 空引用检查的良好实践是什么?
检查对象上的空引用最有效的方法是什么?我见过各种各样的代码示例,它们有不同的检查方法,那么下面哪一种是最有效的,还是被认为是最佳实践C# 空引用检查的良好实践是什么?,c#,performance,C#,Performance,检查对象上的空引用最有效的方法是什么?我见过各种各样的代码示例,它们有不同的检查方法,那么下面哪一种是最有效的,还是被认为是最佳实践 Object.ReferenceEquals(item, null) item == null item != null Object.Equals(item, null) 谢谢前两个实际上是一样的 然而,最后一个不只是做引用检查,不应该用于空检查。我总是使用 item != null 但这比你想象的更难理解 item == null Object.R
Object.ReferenceEquals(item, null)
item == null
item != null
Object.Equals(item, null)
谢谢前两个实际上是一样的 然而,最后一个不只是做引用检查,不应该用于空检查。我总是使用
item != null
但这比你想象的更难理解
item == null
Object.ReferenceEquals用于检查两个对象是否为同一实例。要与
null
进行比较,我将使用==
或=
始终,因为对于null
而言,它应该始终给出与ReferenceEquals
和Equals
相同的结果(因此不需要额外的代码)
编辑:确实可以覆盖
=
,为null
(即true
)提供错误的结果,但这意味着覆盖有缺陷。为了使代码可读,我将坚持使用==
和=
ReferenceEquals
相当于(object)o1==(object)o2
。如果相等运算符重载,它可能比o1==o2
快Object.Equals
可能会稍微慢一点
==
和之间的区别=代码>不是性能,而是程序的外观。如果==
和,它们可能会稍微慢一点=代码>运算符重载
但我认为它们之间的性能差异根本不重要。我会选择最容易阅读的。这通常是==
或=代码>
如果我抛出异常,我通常使用==
,如下所示:
if(o == null)
throw new ...;
如果null
导致无操作,则通常=代码>是合适的
if(x != null)
{
...
}
Object.ReferenceEquals(item,null)
比较引用和等于item==null
Object.Equals(item,null)
比较引用类型的引用和值类型的按位引用,但在reflector中它等于(item==null)|((item!=null&&null!=null)&&item.Equals(null))
项目!=空
代码并不总是等于!(item==null)
,但结果当然应该相等
item==null
code不等于null==item
,它类似于typeof(item).equals(object)
和object.equals(typeof(item))
方法调用
它的不同之处在于您可以覆盖=代码>,==
,等于
。
使用具有已知实现的方法,null==item
更好地编码,但更难阅读。
对象。ReferenceEquals(null,item)
可能更快,也可能更快
另外,也要使用string.IsNullOrEmpty(item)作为额外选项,不要忘记.NET4.0中的代码契约
System.Diagnostics.Contracts.Contract.Requires(item != null);
这不仅是好的和清晰的,而且允许编译时检查。请参阅msdn中的。更新的答案
从C#7.0开始,您可以使用:
item is null
应该是最简单、最简单的方法。它与ReferenceEquals
check相同
旧答案:
1)
这是一个好办法。虽然没有我喜欢的那么简洁,但仍然很好,并准确地告诉了你意图
2)
如果您确信=
以及随后的,那么这个(是最优雅的)没有什么问题=代码>已正确重载。它很容易编写(重载)错误的相等运算符(并且经常这样做)。但真正的问题是当您试图在类中重载=
操作符时(比如说值语义)您不能在类的==
重载函数中使用=
进行空检查。要有一个一致的风格,我依赖于其他东西
3)
同样,它在内部执行一个ReferenceEquals
,因此没有太多意义,但如果它在语义上对您更有意义,那么就这样做吧
4)
我的方法是
(object)item == null
在此基础上,我依赖于对象
自己的相等运算符,它不会出错。可读性不强,所以我只包装了一个自定义扩展方法和一个重载:
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;
}
(不要取下(对象)
强制转换,因为这将在重载=
时防止无限递归,如前所述)
此外,该约束阻止值类型上的IsNull
。现在它就像呼唤一样甜美
object obj = new object();
Guid? guid = null;
bool b = obj.IsNull(); // false
b = guid.IsNull(); // true
2.IsNull(); // error
我还发现(object)item==null
是或object.Equals(,)
,但前提是它很重要(我目前正在做一些事情,我必须对所有内容进行微优化!)
要查看有关实施平等性检查的完整指南,请参见《如何理解<代码>》=
比=
更难阅读?根据您使用的字体,感叹号比等号更难看到。这些是更少的像素!than=例如,如果您在(!bool)中使用比(bool==false)更容易漏掉,我想这取决于您是否有视力受损的员工!如果这对你来说是个问题,听起来你需要在IDE中切换字体。这对我来说不是问题,这是我在阅读关于代码可读性的文章时学到的东西。我使用Droid字体,如果我无法阅读自己的代码,我会更改它:p我喜欢null==item
,因为在许多语言中,如果程序员不小心说item=null
,编译器会很高兴地赋值并返回true,而不是执行比较。但是null=item
在每种语言中都是无效的,基本上所有的编译器都会捕捉到它。假设其中一种语言的速度比其他语言慢10倍,您就使用了它。你注意到了吗?除非它在一个罕见的昂贵热点
(object)item == null
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;
}
public static bool IsNull<T>(this T obj) where T : class
{
return (object)obj == null || obj == DBNull.Value;
}
object obj = new object();
Guid? guid = null;
bool b = obj.IsNull(); // false
b = guid.IsNull(); // true
2.IsNull(); // error