gpt4 book ai didi

c# - 空检查的 "is"类型模式表达式

转载 作者:太空狗 更新时间:2023-10-29 21:37:27 26 4
gpt4 key购买 nike

我可以重构这段代码(流行的 as/null check 模式)

var a = b as MyType;
if(a != null) { ... }

..变成一个不错的"is" type pattern expression :

if(b is MyType a) { ... }

..这很酷...我认为...是吗?


但是现在我也在考虑重构

var a = SomeMethod();
if(a != null) { ... }

..进入:

if(SomMethod() is MyType a) { ... }

注意:没有 as 并且 SomeMethod() 已经返回 MyType。它看起来像 (pseudocode) if(A is A) 并且很容易混淆,不是吗?

第一个重构是合法的,那么后一个呢?我不是 IL 专家来检查自己,C# 7.0 功能对我来说仍然是新的。或许还有我没有发现的问题?

最佳答案

显然这 2 个实现非常相似,内存分配周期 的差异可以忽略不计。

编译器基本上按如下方式处理它们(对于引用类型)

首先

MyType myType = SomeMethod();
if (myType != null)
{
Console.WriteLine(myType.ToString());
}

第二

MyType myType2;
if ((object)(myType2 = SomeMethod()) != null)
{
Console.WriteLine(myType2.ToString());
}

使用 IL 可能会更好看

首先

IL_0000: ldarg.0
IL_0001: call instance class C/MyType C::SomeMethod()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0015

IL_000a: ldloc.0
IL_000b: callvirt instance string[mscorlib] System.Object::ToString()
IL_0010: call void[mscorlib] System.Console::WriteLine(string)

第二

IL_0015: ldarg.0
IL_0016: call instance class C/MyType C::SomeMethod()
IL_001b: dup
IL_001c: stloc.1
IL_001d: brfalse.s IL_002a

IL_001f: ldloc.1
IL_0020: callvirt instance string[mscorlib] System.Object::ToString()
IL_0025: call void[mscorlib] System.Console::WriteLine(string)

注意 : 你可以查看反汇编、IL 和 jit-asm here

IL 的区别基本上是 2 个操作码:

  • dup : 复制计算堆栈上当前最顶层的值,然后将副本压入计算堆栈。
  • Ldloc :将特定索引处的局部变量加载到计算堆栈上。

Jitted 时,它很可能优化到相同的 指令 无论如何


总结

  1. 没有明显的技术差异。
  2. 是的,我想 is 版本更整洁、更简洁。
  3. 它可能是更多可打印字符,所以如果您有可打印字符强制症或遭受残酷的代码审查,这可能不是一件好事
  4. 如果您喜欢它并且您的团队也喜欢它,那就去做吧。
  5. 这不是我的菜

关于c# - 空检查的 "is"类型模式表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55633181/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com