【问题标题】:Proper null check on service result in c# .net在 c# .net 中对服务结果进行正确的空检查
【发布时间】:2020-02-18 15:58:24
【问题描述】:

a tweet from Jared Parsons 是 c# 编译器开发人员。该推文声称我们应该使用“is object”作为非空检查。

我的问题是为什么会这样,如果我从服务调用中得到结果,我应该运行“is object”检查而不是“!= null”吗?

根据我的理解以及我在 Microsoft 文档 "is" keyword should be used as type check 中看到的内容。

我无法在 Microsoft 文档中的任何地方找到“is object”作为非空检查示例,这就是为什么我担心这是否真的是进行空检查的正确方法。

【问题讨论】:

  • ==!= 可以重载,在这种情况下,nullity 的语义可能是意料之外的。使用is object!(x is null) 保证参考比较。
  • vc 74 - 您能否提供有关如何重载 == 或 != 的示例?
  • 复制根本不是一个好的选择。它没有解释为什么需要is objectis null,或者有什么优势。
  • 这是我为运算符重载得到的第一个 SO 搜索结果 == stackoverflow.com/a/25461680/1462295
  • @ChrisT 不,这可能非常令人困惑,但Equals 可能具有与== 完全不同的行为,此外,== 在编译时解析,Equals 在运行时解析。如果你真的想检查 x 是否为空引用,C#7 之前的唯一选择是使用object.ReferenceEquals。模式匹配带来了新的选择。

标签: c# .net null


【解决方案1】:

Jared Parsons 是对的(显然),这不是意见问题。有具体的优点。尽可能使用is objectis null。现在看起来很不寻常,但将来会变得更加普遍。


直到 C# 7,is 仅用于类型检查。但从 C# 7 开始,它也用于模式匹配。 is null 是一个常量模式,当输入正好是 null 时匹配。 is objectis string s 匹配类型。

is nullis object 更可取,因为有人可以重载 Equals== 运算符。例如,两个大小相等的盒子可以被认为是相等的。 x==null 使用类型的相等运算符,并且仅当该运算符表示为 true 时才会返回 true。

如果有一个错误,或者如果有人试图在平等方面变得聪明,会发生什么?而当我们只需要知道该值是否为空时,为什么还要浪费 CPU 来调用该运算符?

Operator overloading ==, !=, Equals 问题的答案之一显示了问题:

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;
}

【讨论】:

  • 太棒了!谢谢你,它一步一步地解释了很多。所以我明白我的假设是正确的,如果没有相等运算符重载,那么“!= null”和“is object”在任何方面都没有区别。
  • @ChrisT 但你怎么知道,除非它是你的代码?
  • 是的,假设项目 100% 是我自己的代码,并且我确定我没有在任何地方实现相等运算符重载,那么如果我使用“!= null”或“is object”没有太大区别“ 正确的?除非有性能差异,否则有什么区别吗?
  • @ChrisT 不是我知道的,但我不太信任自己的代码,或者我不会在未来引入错误 - 在这种情况下,未来意味着下周五之前你下班了。安全总比抱歉和is null 尽可能
猜你喜欢
  • 2011-07-12
  • 2018-08-13
  • 1970-01-01
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多