【问题标题】:Use of the is keyword to check if a nullable is not null使用 is 关键字检查可空对象是否不为空
【发布时间】:2020-01-08 14:24:34
【问题描述】:

我刚刚发现,可以在 C# 中使用 is-keyword 对可空结构进行空检查。我认为它看起来很干净并且很好理解,但它也有性能吗?口译员必须双重转换还是可以这样?

    static void Main(string[] args)
    {
        DateTime? test = null;

        PrintDT(test);//wont print
        test = DateTime.Now;
        PrintDT(test);//will print
    }
    private static void PrintDT(DateTime? dt)
    {
        if (dt is DateTime a)
            Console.WriteLine(a);
    }

【问题讨论】:

  • 如果你投射任何未知的东西,比如对象到 DateTime,就可以了。但如果源类型已经是 DateTime?,最好使用 dt.HasValue,如果为 true,则使用 dt.Value。这不涉及铸造或装箱,它只是访问它。
  • @Holger 完全不同意。作为语言的一部分,编译器知道如何处理可空类型,并且(典型的)程序员不需要深入研究可空类型的实现细节。
  • @JesseC.Slicer,我不知道你在说什么。日期时间类型?只有两个公共属性 HasValue 和 Value。那不是“实现细节”,那是基础。你说类似的话,然后使用 List,你不需要了解 List.Add。这是将可空值类型转换为其不可空类型的推荐方法。使用 nullables 的程序员必须知道,否则他不能使用这种数据类型。
  • @Holger 也不正确。 dt != null 等价于dt.HasValue(DateTime)dt 等价于dt.Value。你根本不需要知道这些方法。
  • @JesseC.Slicer 是的,有隐式应用的强制转换规则。但这个讨论强烈地基于意见。我更喜欢显式而不是隐式,并且 Intellisense 会自行建议这些属性,学习起来并不难。没关系,做事的方法不止一种,但永远没有方法的排名。对于性能,您需要了解一些细节。这里的主题是 is-operator。你同意,我们不应该使用它,因为它也不属于你的答案。

标签: c# .net .net-core


【解决方案1】:

任何编译/反编译回C#的工具都会给出等效的方法(发布模式编译):

private static void PrintDT(DateTime? dt)
{
    if (dt.HasValue)
    {
        DateTime valueOrDefault = dt.GetValueOrDefault();
        Console.WriteLine(valueOrDefault);
    }
}

或(调试模式编译)

private static void PrintDT(DateTime? dt)
{
  DateTime valueOrDefault;
  int num;
  if (dt.HasValue)
  {
    valueOrDefault = dt.GetValueOrDefault();
    num = 1;
  }
  else
    num = 0;
  if (num == 0)
    return;
  Console.WriteLine((object) valueOrDefault);
}

因此编译器在前面使用可空类型语法糖在幕后创建优化场景。

【讨论】:

  • 但是if (dt.HasValue) Console.WriteLine(dt.Value); 会不会更好,因为我们不必引入新变量?还是编译器无论如何都会进行清理,以便最终保持相同?
  • 我只是展示了反编译器的功能。我同意你对这个案子的说法。我的猜测是编译器无法做出我们可以查看代码的某些假设。我敢肯定,像 Eric Lippert 或 Jon Skeet 这样的人可以准确地解释它为什么会这样做,但请放心,它属于“不要搞砸”标题。
  • @MaxR。变量只是名称,而不是实际值。此外,即使在 .NET Old 中,GetValueOrDefault 也只是返回值
  • @PanagiotisKanavos 所以如果我理解正确的话,最终性能不会受到任何方面的影响?
  • @MaxR。如果您检查链接,您会看到.Value 在调用return value 之前执行检查,如果失败则抛出,因此GetValueOrDefault 更快... 1 CPU 操作在好的情况下或支付成本如果为空则抛出
猜你喜欢
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多