gpt4 book ai didi

c# - MethodBody.LocalVariables 计数令人困惑

转载 作者:太空宇宙 更新时间:2023-11-03 11:24:50 24 4
gpt4 key购买 nike

对于像下面这样没有局部变量的简单方法

public static int Test1(short i, long j)
{
j = i + j;

switch (j)
{
case 1:
j = 2;
break;
default:
j = 11;
break;
}

return j;
}

MethodInfo.GetMethodBody().LocalVariables.Count 的计数 = 2 为什么?添加另一个 switch 语句,计数变为 3 为什么?

public static int Test1(short i, long j)
{
j = i + j;

switch (j)
{
case 1:
j = 2;
break;
default:
j = 11;
break;
}

switch (i)
{
case 1:
j = 2;
break;
default:
j = 11;
break;
}

return j;
}

没有定义局部变量。那么为什么是 2 和 3。此外,如果另一个带有 j 的 switch 语句将计数保持在 2。

最佳答案

我认为,C# 编译器生成的局部变量不在您的 C# 源代码中这一事实是意料之中的。这是因为 IL 堆栈并不总是存储一些临时值的好地方,因为您只能访问它的顶部。

这尤其适用于调试版本,因为它们针对调试进行了优化,而不是针对性能或内存占用。我不知道这些本地人如何帮助调试器,或者他们是否有帮助,但我假设他们确实有他们的观点。

具体来说,正如 jmh_gr 所指出的,您的方法实际上不会编译,因为您不能将 long 隐式转换为 int。如果我将 j 的类型更改为 int,它会在使用调试配置时生成如下代码(使用 Reflector 反编译,禁用优化):

public static int Test1(short i, int j)
{
int CS$1$0000;
int CS$4$0001;
j = i + j;
CS$4$0001 = j;
if (CS$4$0001 != 1)
{
goto Label_0013;
}
j = 2;
goto Label_0019;
Label_0013:
j = 11;
Label_0019:
CS$1$0000 = j;
Label_001D:
return CS$1$0000;
}

所以,你看,这个方法实际上有两个局部变量,而且都被使用了。使用发布配置时,生成的 IL 只有一个局部变量,如下所示:

public static int Test1(short i, int j)
{
int CS$0$0000;
j = i + j;
CS$0$0000 = j;
if (CS$0$0000 != 1)
{
goto Label_0010;
}
j = 2;
goto Label_0014;
Label_0010:
j = 11;
Label_0014:
return j;
}

看起来 local 不是必需的,但也许有一个很好的理由。当然,对性能真正重要的是 JIT 编译的程序集,而不是 IL 代码。

关于c# - MethodBody.LocalVariables 计数令人困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9746169/

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