gpt4 book ai didi

c# - 这个编译器生成的枚举数是什么意思?

转载 作者:太空狗 更新时间:2023-10-30 00:22:36 27 4
gpt4 key购买 nike

我写了一个相当复杂的方法来返回 IEnumerable<string> ,但是当我检查 Reflector 中的编译器输出时,我不理解编译器生成的 IEnumerator 实现的特定部分:

void IDisposable.Dispose()
{
switch (this.<>1__state)
{
case 1:
case 2:
case 3:
switch (this.<>1__state) // empty switch! why?!
{
}
break;

default:
return;
try // What?! AFTER return?!
{
}
finally // is the try-finally block anyhow relevant?
{
this.<>m__Finallya();
}
break;
}
this.<>m__Finally7();
}

我猜测(或希望)Reflector 错放了外部 switch 的右大括号, 它应该直接在 return 之后.仍然,我不明白为什么情况 3 中有一个空开关,或者为什么 m__Finallyafinally 中被调用堵塞。 (正常运行和在 finally block 内运行之间是否存在语义差异?除了 CER,我的代码中没有。)

作为引用,这里是 IL:

.method private hidebysig newslot virtual final 
instance void System.IDisposable.Dispose() cil managed
{
.override [mscorlib]System.IDisposable::Dispose
// Code size 69 (0x45)
.maxstack 2
.locals init ([0] int32 CS$0$0000,
[1] int32 CS$0$0001)
IL_0000: ldarg.0
IL_0001: ldfld int32 FBD.TIP.Reader.MissingMessagesReader/'<GetMissingMessages>d__0'::'<>1__state'
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.1
IL_0009: sub
IL_000a: switch (
IL_001c,
IL_001c,
IL_001c)
IL_001b: ret
IL_001c: ldarg.0
IL_001d: ldfld int32 FBD.TIP.Reader.MissingMessagesReader/'<GetMissingMessages>d__0'::'<>1__state'
IL_0022: stloc.1
IL_0023: ldloc.1
IL_0024: ldc.i4.2
IL_0025: sub
IL_0026: switch (
IL_0035,
IL_0035)
IL_0033: br.s IL_003e
.try
{
IL_0035: leave.s IL_003e
} // end .try
finally
{
IL_0037: ldarg.0
IL_0038: call instance void FBD.TIP.Reader.MissingMessagesReader/'<GetMissingMessages>d__0'::'<>m__Finallya'()
IL_003d: endfinally
} // end handler
IL_003e: ldarg.0
IL_003f: call instance void FBD.TIP.Reader.MissingMessagesReader/'<GetMissingMessages>d__0'::'<>m__Finally7'()
IL_0044: ret
} // end of method '<GetMissingMessages>d__0'::System.IDisposable.Dispose

最佳答案

你还没有展示你的原始迭代器 block 是什么样子的,但我对 Reflector 和编译器生成的代码的经验是,它并不总是能够完全准确地反编译,因为编译器使用了一些没有的 IL C# 中的等价物。

我有一个 article about iterator block implementation这可能会对你有所帮助,但我不会太担心编译代码的样子。在某些情况下,C# 编译器几乎肯定会生成不必要的代码,理由是使编译器更简单。迭代器 block 一定很难正确处理(它可能会变得非常复杂,finally block 和迭代器处理)所以我认为相信 JIT 可以优化掉生成代码中不必要的位(如 switch/case)是合理的。

关于c# - 这个编译器生成的枚举数是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/555796/

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