模式匹配等于空值与空值



来自 c-7-0 中的Microsoft新功能:

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 == nullo is null的区别是什么?

由于@xanatos的答案已经过时(但仅在最后提到),我正在写一个新的,因为我也想知道这一点并研究了它。

简而言之:如果您不重载==运算符,则o == nullo is null是相同的.
如果您确实重载了==运算符,那么o == null会调用它,但o is null不会

o is null总是做与ReferenceEquals(o, null)相同的操作,即它检查值是否为空,它不调用任何运算符或Equals方法。

更长的答案:这是一个 SharpLab 示例,展示了检查 null 的各种方法。

如果以 IL 形式查看结果,则会看到:

  • is nullReferenceEquals产生相同的代码
  • o == null将调用重载operator==
  • object.Equals(o, null)调用该方法
  • 如果您在类C中注释operator==,您将看到o == null现在生成的代码与o is null

o is null被翻译成object.Equals(null, o)(你可以在这里看到它)。

object.Equals代码编写为:

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(oSystem.Object)应该比o is null(更少的操作)更快......但谁知道呢?:-)

最终结果是,通过两条不同的路由,o is nullo == null(oSystem.Object)返回相同的结果。

通过查看,我们甚至可以看到o == nullobject.ReferenceEquals(o, null)相同(oSystem.Object):-)。

有趣的问题应该是,为什么 C# 编译器不将x is null转换为object.ReferenceEquals(x, null)请注意,由于可空类型的装箱方式,它甚至可以用于:

int? a = null;
if (a is null) { /* */ }

对编译器的更改使此响应无效...如果您单击"此处"链接,您可以看到它

"is"和==之间的区别是"is"的特殊之处在于,如果您与值进行比较,它充当==,当您将对象的类型与类型进行比较时,它充当typeof(type)。

最新更新