Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 循环内的委托如何理解局部变量和循环变量之间的差异_C#_Loops_Closures - Fatal编程技术网

C# 循环内的委托如何理解局部变量和循环变量之间的差异

C# 循环内的委托如何理解局部变量和循环变量之间的差异,c#,loops,closures,C#,Loops,Closures,看看这段代码 List<Action> actions = new List<Action>(); for (int variable = 0; variable < 5; ++variable) { int myLocalVariable = variable; actions.Add(() => Console.WriteLine(myLocalVariable));

看看这段代码

    List<Action> actions = new List<Action>();
    for (int variable = 0; variable < 5; ++variable)
        {
            int myLocalVariable = variable;
            actions.Add(() => Console.WriteLine(myLocalVariable));
        }
    actions.ForEach(s => s.Invoke());
    Console.ReadLine();
List actions=new List();
对于(int变量=0;变量<5;++变量)
{
int myLocalVariable=变量;
actions.Add(()=>Console.WriteLine(myLocalVariable));
}
actions.ForEach(s=>s.Invoke());
Console.ReadLine();
输出为01 2 3 4

查看IL代码,我倾向于认为编译器只创建了myLocalVariable的一个实例。这一事实也证实了在循环中使用局部变量的良好实践

那么,actions.Add()中的委托如何存储循环变量的“最新”版本呢

查看IL代码,我倾向于认为编译器只创建了myLocalVariable的一个实例

没有。C#语言规范清楚地表明,变量在循环的每次迭代中都会实例化——因此每次迭代都有一个单独的变量,并且它们被单独捕获

根据C#5规范第7.5.15.2节:

当执行进入局部变量的作用域时,该局部变量被认为是实例化的。例如,当调用下面的方法时,局部变量x被实例化并初始化三次,每次循环迭代一次

static void F() {
    for (int i = 0; i < 3; i++) {
        int x = i * 2 + 1;
        ...
    }
}
static void F(){
对于(int i=0;i<3;i++){
int x=i*2+1;
...
}
}
但是,将x的声明移到循环之外会导致
x的单个实例化

未捕获时,无法准确观察局部变量实例化的频率,因为实例化的生命周期是不相交的,每个实例化都可能使用相同的存储位置。但是,当匿名函数捕获局部变量时,实例化的效果变得明显

查看IL代码,我倾向于认为编译器只创建了myLocalVariable的一个实例

没有。C#语言规范清楚地表明,变量在循环的每次迭代中都会实例化——因此每次迭代都有一个单独的变量,并且它们被单独捕获

根据C#5规范第7.5.15.2节:

当执行进入局部变量的作用域时,该局部变量被认为是实例化的。例如,当调用下面的方法时,局部变量x被实例化并初始化三次,每次循环迭代一次

static void F() {
    for (int i = 0; i < 3; i++) {
        int x = i * 2 + 1;
        ...
    }
}
static void F(){
对于(int i=0;i<3;i++){
int x=i*2+1;
...
}
}
但是,将x的声明移到循环之外会导致
x的单个实例化

未捕获时,无法准确观察局部变量实例化的频率,因为实例化的生命周期是不相交的,每个实例化都可能使用相同的存储位置。但是,当匿名函数捕获局部变量时,实例化的效果变得明显


好的,请告诉我,如果我是对的,一个匿名函数捕获)局部实例化变量(myLocalVariable)的值,并在内部存储该值的副本,在这种情况下,它可以存储循环变量的值副本,那么匿名函数局部变量与循环变量的区别是什么@JonSkeet@VladimirGabrielyan:没有,因为循环变量被指定为只为
for
循环实例化一次。对于
foreach
循环,它曾经被实例化过一次,但对于C#5来说这是固定的,因此每次迭代都会被实例化。好的,请告诉我我是否正确,一个匿名函数捕获)局部实例化变量(myLocalVariable)的值,并在内部存储该值的副本,在这种情况下,它可以存储循环变量的值副本,那么匿名函数局部变量和循环变量的区别是什么呢@JonSkeet@VladimirGabrielyan:否,因为循环变量被指定为仅为
for
循环实例化一次。对于
foreach
循环,它曾经被实例化一次,但对于C#5来说这是固定的,因此每次迭代都会被实例化。