Blazor嵌套for循环索引变量恒为最大值的问题及原理咨询
问题解析:Razor嵌套循环中索引i始终为6的原因及解决原理
问题场景
想要在Razor文件中通过嵌套for循环,利用循环索引判断显示对应图片,初始代码如下:
@for (int i = 1; i < 6; i++) { <MudItem> @for (int j = 1; j < 6; j++) { stoel = GereserveerdeStoelen.Where(s => s.XPositionChair == i && s.YPositionChair == j).SingleOrDefault(); @if (stoel is null) { <MudImage Width="40" Src="images/chair.png" Alt="chair" Class="d-flex align-center justify-center py-8" /> } else { <MudImage Width="40" Src="images/chair_not.png" Alt="chair" Class="d-flex align-center justify-center py-8" /> } } </MudItem> }
运行后发现异常:所有循环中索引i的值始终为6。参考Lambda捕获变量的解决方案,将i赋值给循环内的局部变量后问题解决,修改后的代码:
@for (int i = 1; i < 6; i++) { int local = i; <MudItem> @for (int j = 1; j < 6; j++) { stoel = GereserveerdeStoelen.Where(s => s.XPositionChair == local && s.YPositionChair == j).SingleOrDefault(); @if (stoel is null) { <MudImage Width="40" Src="images/chair.png" Alt="chair" Class="d-flex align-center justify-center py-8" /> } else { <MudImage Width="40" Src="images/chair_not.png" Alt="chair" Class="d-flex align-center justify-center py-8" /> } } </MudItem> }
问题成因
这是变量引用捕获导致的问题:
- Razor页面的渲染和Lambda表达式的执行是延迟的,并非在循环迭代时立即执行
Where里的条件判断。 - 循环中的
i是一个全局于外层循环的变量,所有迭代的Lambda表达式捕获的都是这个变量的引用,而不是当前迭代的i的值。 - 当循环结束时,
i的值已经递增到6(因为循环条件是i < 6,最后一次循环后i变成6才退出),此时所有延迟执行的Lambda表达式才会使用这个最终的i值,导致所有判断都用了6。
解决方案原理
在每次外层循环迭代中创建一个局部变量local并赋值为i:
- 每次循环都会生成一个全新的
local变量,它的作用域仅限于当前迭代。 - Lambda表达式捕获的是当前迭代的
local变量的引用,而这个local保存的是当前迭代时i的具体值(比如第一次循环是1,第二次是2,以此类推)。 - 当后续Lambda执行时,每个捕获的
local都对应各自迭代的正确值,不会被循环后续的变量更新影响。
内容的提问来源于stack exchange,提问作者Tigris
相关产品推荐
相关产品推荐

