C# 关闭。它如何改变结构类型的变量?
C# closure. How it changes the variable of struct type?
类似于:How do closures work behind the scenes? (C#)
假设我们有代码:
static void Main(string[] args)
{
int i = 100;
Action d = () => { i++; };
d();
Console.WriteLine(i.ToString());
}
我们将看到结果“101”。
我知道,如果匿名函数捕获局部变量,它会创建一个新的 class,其中包含与匿名函数相关的局部变量和方法字段。
所以这个 class 看起来像(伪代码):
private class DisplayClass1
{
public int i;
public void Main(){ i++; }
}
使用 ILDasm.exe 我们看到生成了 class:
然后程序的主要方法将如下所示(伪代码):
static void Main(string[] args)
{
int i = 100;
//create helper class
DisplayClass1 class1 = new DisplayClass1();
//initialize fields
class1.i = i;
//crete instance of delegate
Action d = new Action(class1.Main);
d.Invoke();
Console.WriteLine(i.ToString());
}
很清楚它是如何改变引用类型的实例的。但是它如何与结构一起工作?
我猜它在 d.Invoke();
之后又添加了一行,例如 i = class1.i;
(多线程有任何问题吗?)或者在 DisplayClass1.Main
中执行一些特殊操作以从堆栈访问相同的变量。
这是此方法的 IL 代码:
.method public hidebysig instance void '<Main>b__0'() cil managed
{
// Code size 16 (0x10)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: dup
IL_0003: ldfld int32 ConsoleApplication3.Program/'<>c__DisplayClass1'::i
IL_0008: ldc.i4.1
IL_0009: add
IL_000a: stfld int32 ConsoleApplication3.Program/'<>c__DisplayClass1'::i
IL_000f: ret
} // end of method '<>c__DisplayClass1'::'<Main>b__0'
我不是 MSIL 方面的专家。有什么想法吗?
您的伪代码不太正确。它实际上用闭包 class 的字段替换了所有对 local 的使用:
static void Main(string[] args)
{
//create helper class
DisplayClass1 class1 = new DisplayClass1();
//initialize fields
class1.i = 100;
//crete instance of delegate
Action d = new Action(class1.Main);
d.Invoke();
Console.WriteLine(class1.i.ToString());
}
类似于:How do closures work behind the scenes? (C#)
假设我们有代码:
static void Main(string[] args)
{
int i = 100;
Action d = () => { i++; };
d();
Console.WriteLine(i.ToString());
}
我们将看到结果“101”。
我知道,如果匿名函数捕获局部变量,它会创建一个新的 class,其中包含与匿名函数相关的局部变量和方法字段。
所以这个 class 看起来像(伪代码):
private class DisplayClass1
{
public int i;
public void Main(){ i++; }
}
使用 ILDasm.exe 我们看到生成了 class:
然后程序的主要方法将如下所示(伪代码):
static void Main(string[] args)
{
int i = 100;
//create helper class
DisplayClass1 class1 = new DisplayClass1();
//initialize fields
class1.i = i;
//crete instance of delegate
Action d = new Action(class1.Main);
d.Invoke();
Console.WriteLine(i.ToString());
}
很清楚它是如何改变引用类型的实例的。但是它如何与结构一起工作?
我猜它在 d.Invoke();
之后又添加了一行,例如 i = class1.i;
(多线程有任何问题吗?)或者在 DisplayClass1.Main
中执行一些特殊操作以从堆栈访问相同的变量。
这是此方法的 IL 代码:
.method public hidebysig instance void '<Main>b__0'() cil managed
{
// Code size 16 (0x10)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: dup
IL_0003: ldfld int32 ConsoleApplication3.Program/'<>c__DisplayClass1'::i
IL_0008: ldc.i4.1
IL_0009: add
IL_000a: stfld int32 ConsoleApplication3.Program/'<>c__DisplayClass1'::i
IL_000f: ret
} // end of method '<>c__DisplayClass1'::'<Main>b__0'
我不是 MSIL 方面的专家。有什么想法吗?
您的伪代码不太正确。它实际上用闭包 class 的字段替换了所有对 local 的使用:
static void Main(string[] args)
{
//create helper class
DisplayClass1 class1 = new DisplayClass1();
//initialize fields
class1.i = 100;
//crete instance of delegate
Action d = new Action(class1.Main);
d.Invoke();
Console.WriteLine(class1.i.ToString());
}