在许多情况下,我认为可以使用的一种方法是将switch
语句的每个选项封装在本地范围内。
后来添加:
C#源代码中存在的本地作用域块{ ... }
似乎与生成的IL字节码无关。 我尝试了这个简单的例子:
static void A()
{
{
var o = new object();
Console.WriteLine(o);
}
var p = new object();
Console.WriteLine(p);
}
static void B()
{
var o = new object();
Console.WriteLine(o);
var p = new object();
Console.WriteLine(p);
}
static void C()
{
{
var o = new object();
Console.WriteLine(o);
}
{
var o = new object();
Console.WriteLine(o);
}
}
这是在启用优化的发布版模式下编译的。根据IL DASM生成的结果如下:
.method private hidebysig static void A() cil managed
{
.maxstack 1
.locals init ([0] object o,
[1] object p)
IL_0000: newobj instance void [mscorlib]System.Object::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call void [mscorlib]System.Console::WriteLine(object)
IL_000c: newobj instance void [mscorlib]System.Object::.ctor()
IL_0011: stloc.1
IL_0012: ldloc.1
IL_0013: call void [mscorlib]System.Console::WriteLine(object)
IL_0018: ret
}
->
.method private hidebysig static void B() cil managed
{
.maxstack 1
.locals init ([0] object o,
[1] object p)
IL_0000: newobj instance void [mscorlib]System.Object::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call void [mscorlib]System.Console::WriteLine(object)
IL_000c: newobj instance void [mscorlib]System.Object::.ctor()
IL_0011: stloc.1
IL_0012: ldloc.1
IL_0013: call void [mscorlib]System.Console::WriteLine(object)
IL_0018: ret
}
→
.method private hidebysig static void C() cil managed
{
.maxstack 1
.locals init ([0] object o,
[1] object V_1)
IL_0000: newobj instance void [mscorlib]System.Object::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call void [mscorlib]System.Console::WriteLine(object)
IL_000c: newobj instance void [mscorlib]System.Object::.ctor()
IL_0011: stloc.1
IL_0012: ldloc.1
IL_0013: call void [mscorlib]System.Console::WriteLine(object)
IL_0018: ret
}
结论:
- 在 IL 字节码中,局部作用域声明不存在任何形式。
- C# 编译器将为可能存在冲突的局部变量选择新名称(例如
C
方法中的第二个变量 o
)。
- 认为引入 C# 源代码中的局部作用域可以使垃圾回收器尽早执行其工作的人是错误的(请参见其他答案和问题的评论)。
我还尝试以 调试 模式(无优化)编译此代码。局部作用域的开始和结束似乎仅显示为 nop
指令(“无操作”)。在某些情况下,来自不同局部作用域的两个具有相同名称的局部变量被映射到 IL 中的同一局部变量,就像上面命名为 C
的 C# 方法一样。仅当它们的类型兼容时才可能对两个变量进行“统一”。