有一条来自 C# 编译器开发人员 Jared Parsons 的推文。这条推文声称我们应该使用"is object"作为非空检查。
我的问题是为什么会这样,如果我从服务调用中获得结果,我应该运行"是对象"检查而不是"!= null"吗?
根据我的理解以及我在文档中可以看到Microsoft"is"关键字应该用作类型检查。
我无法在文档中的任何地方找到"is object"作为非空检查示例Microsoft这就是为什么我担心这是否真的是进行空检查的正确方法。
Jared Parsons是对的(显然(,这不是一个意见问题。有具体的好处。尽可能使用is object
或is null
。它现在看起来很不寻常,但将来会变得更加普遍。
在 C# 7 之前,is
仅用于类型检查。不过,从 C# 7 开始,它也用于模式匹配。is null
是一个常量模式,当输入正好null
时匹配。is object
或is string s
类型匹配。
is null
和is object
更可取,因为有人可以使Equals
超载并==
操作员。例如,两个大小相等的盒子可以被认为是相等的。x==null
使用该类型的相等运算符,并且仅当该运算符表示为 true 时才返回 true。
但是,如果存在错误,或者如果有人试图在平等方面变得聪明,会发生什么?当我们只需要知道该值是否为空时,我们为什么要浪费 CPU 来调用该运算符?
运算符重载 ==, !=, 等于问题的答案之一显示了问题:
operator ==()
中的代码:
public class BOX
{
public double Height{get;set;}
public double Length{get;set;}
public double Breadth{get;set;}
public static bool operator == (BOX b1, BOX b2)
{
if ((object)b1 == null)
return (object)b2 == null;
return b1.Equals(b2);
}
...
开始于 :
public static bool operator == (BOX b1, BOX b2)
{
if (b1 == null)
return (b2 == null);
return b1.Equals(b2);
}
哎呀 - 这是无限递归!这些比较中的每一个最终都会再次调用operator ==
。如果我们自己的代码使用了:
if (theBoxFromDB == null) ...
我们也会得到无限递归。回答者通过强制转换为object
来解决这个问题,从而强制使用Object.Equals
进行比较。
我们可以避免这种不幸的情况,但如果我们使用:
if (theBoxFromDB is null) ...
相等运算符本身可以通过这种方式简化。没有额外的演员,没有像其他答案那样打电话ReferenceEquals
。 :
public static bool operator == (BOX b1, BOX b2)
{
if (b1 is null)
return (b2 is null);
return b1.Equals(b2);
}
当我们开始使用完整的模式匹配语法时,事情变得更加有趣。if(box is null)
我们唯一知道的是盒子是null
.
但是,如果我们使用语法is T name
,我们会得到一个强类型的非空变量:
object box=LoadFromSomewhere();
if(box is Box b)
{
var volume=box.Height*box.Width*box.Breadth;
}