模式匹配 equal null vs is null
Pattern matching equal null vs is null
来自 Microsoft new-features-in-c-7-0:
public void PrintStars(object o)
{
if (o is null) return; // constant pattern "null"
if (!(o is int i)) return; // type pattern "int i"
WriteLine(new string('*', i));
}
o == null
和o is null
有什么区别?
把o is null
翻译成object.Equals(null, o)
(大家可以看看here)。
object.Equals
代码is written as:
public static bool Equals(Object objA, Object objB)
{
if (objA == objB)
{
return true;
}
if (objA == null || objB == null)
{
return false;
}
return objA.Equals(objB);
}
所以最后会有一个o == null
(第一个if
)。请注意,System.Object
没有定义 operator==
,因此使用的是引用类型,即引用相等性。
理论上,通过观察被调用的代码,可以认为 o == null
(o
和 System.Object
)应该比 o is null
(更少的操作)更快。 .. 但是谁知道呢? :-)
最终的结果是,通过两条不同的路线,o is null
和o == null
(with o
a System.Object
)return结果相同。
通过查看我们甚至可以看到 o == null
与 object.ReferenceEquals(o, null)
相同(o
和 System.Object
):-)。
有趣的问题应该是,为什么 C# 编译器不将 x is null
翻译成 object.ReferenceEquals(x, null)
?。请注意,由于如何完成可空类型的装箱,它甚至可以用于:
int? a = null;
if (a is null) { /* */ }
对编译器的更改使此响应无效...如果您单击 "here" link 您可以看到它
"is" 和 == 之间的区别是 "is" 特别之处在于,如果您与值进行比较,它充当 ==,而当您将对象的类型与类型进行比较时,它充当 typeof(type)。
由于@xanatos的答案已经过时了(但只在最后提到)我正在写一个新的,因为我也想知道这个并研究它。
简而言之:如果不重载==
运算符,那么o == null
和o is null
是一样的。
如果你确实重载了 ==
运算符,那么 o == null
会调用它,但是 o is null
不会 .
o is null
总是与 ReferenceEquals(o, null)
做同样的事情,即它 只 检查值是否为 null,它不调用任何运算符或 Equals
方法。
更长的答案: here is a SharpLab sample 展示了检查 null 的各种方法。
如果您以 IL 形式查看结果,您会看到:
is null
和 ReferenceEquals
产生相同的代码
o == null
将调用重载的 operator==
object.Eqauls(o, null)
调用该方法
- 如果您在 class
C
中注释 operator==
,您将看到 o == null
现在生成与 o is null
相同的代码
来自 Microsoft new-features-in-c-7-0:
public void PrintStars(object o)
{
if (o is null) return; // constant pattern "null"
if (!(o is int i)) return; // type pattern "int i"
WriteLine(new string('*', i));
}
o == null
和o is null
有什么区别?
把o is null
翻译成object.Equals(null, o)
(大家可以看看here)。
object.Equals
代码is written as:
public static bool Equals(Object objA, Object objB)
{
if (objA == objB)
{
return true;
}
if (objA == null || objB == null)
{
return false;
}
return objA.Equals(objB);
}
所以最后会有一个o == null
(第一个if
)。请注意,System.Object
没有定义 operator==
,因此使用的是引用类型,即引用相等性。
理论上,通过观察被调用的代码,可以认为 o == null
(o
和 System.Object
)应该比 o is null
(更少的操作)更快。 .. 但是谁知道呢? :-)
最终的结果是,通过两条不同的路线,o is null
和o == null
(with o
a System.Object
)return结果相同。
通过查看我们甚至可以看到 o == null
与 object.ReferenceEquals(o, null)
相同(o
和 System.Object
):-)。
有趣的问题应该是,为什么 C# 编译器不将 x is null
翻译成 object.ReferenceEquals(x, null)
?。请注意,由于如何完成可空类型的装箱,它甚至可以用于:
int? a = null;
if (a is null) { /* */ }
对编译器的更改使此响应无效...如果您单击 "here" link 您可以看到它
"is" 和 == 之间的区别是 "is" 特别之处在于,如果您与值进行比较,它充当 ==,而当您将对象的类型与类型进行比较时,它充当 typeof(type)。
由于@xanatos的答案已经过时了(但只在最后提到)我正在写一个新的,因为我也想知道这个并研究它。
简而言之:如果不重载==
运算符,那么o == null
和o is null
是一样的。
如果你确实重载了 ==
运算符,那么 o == null
会调用它,但是 o is null
不会 .
o is null
总是与 ReferenceEquals(o, null)
做同样的事情,即它 只 检查值是否为 null,它不调用任何运算符或 Equals
方法。
更长的答案: here is a SharpLab sample 展示了检查 null 的各种方法。
如果您以 IL 形式查看结果,您会看到:
is null
和ReferenceEquals
产生相同的代码o == null
将调用重载的operator==
object.Eqauls(o, null)
调用该方法- 如果您在 class
C
中注释operator==
,您将看到o == null
现在生成与o is null
相同的代码