作者uranusjr (←这人是超级笨蛋)
看板C_Sharp
标题Re: [问题] Closure的问题
时间Tue Apr 7 22:51:58 2015
※ 引述《jamod (jasper)》之铭言:
: 小弟觉得应该是发生Closure的问题吧?
: 我想在10个按钮上面挂10个触发事件,Code大致上像:
: for(int index = 0;index < 10;index++){
: btn[index].onClick += () =>
: {
: Console.WriteLine(index.toString());
: };
: }
: 结果10个按钮按下去,都是10...
for (int i = 0; i < 10; i++) {
int localVariable = i;
btn[i].onClick += () => {
Console.WriteLine(localVariable.toString());
};
}
这里的问题是因为你只宣告了一个 index
所有的 closures 都会 capture 到同一个变数, 而这个变数又是 loop index
当 i++ 时, 所有 closures 都会被影响(因为它们使用的变数是同一个东西)
解法就是为每一个 closure 宣告一个 local variable 来 capture
在这里, 等於每个 iteration 都会把 loop index 复制一份
所以每个 closure capture 到的变数会是独立的, 也与 loop index 独立
就可以绕过你的问题
--
╱ ̄ ̄ ̄╲
▏
◢█◣ ▏
︻█︻█ ▏
成龙表示: 是喔...
′/ ‵ ▏
╰╯ █╱
ψQSWEET ◥︶█◤
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 218.161.94.175
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_Sharp/M.1428418321.A.FC2.html
※ 编辑: uranusjr (218.161.94.175), 04/07/2015 22:53:18
1F:推 jamod: 这个方式我有用过,但是还是会有问题,不知道是否是因为事件 04/07 23:40
2F:→ jamod: 宣告的关系导致的@@? 04/07 23:41
3F:推 J002: 还是试试 var localVariableString = i.toString(); 04/08 21:23
4F:→ J002: Console.WriteLine(localVariableString); 看看? 04/08 21:23
5F:→ pkmu8426: 试试可不可用button本身的id 或tag 属性去记录index 04/10 02:08
6F:→ pkmu8426: 因为button本身是物件, 如果用它自身的属性去记应该比较 04/10 02:08
7F:→ pkmu8426: 不会有问题 04/10 02:08
8F:→ pkmu8426: 我是用winform模拟了 虽然事件宣告建构形式有点差异 04/10 02:09
9F:→ pkmu8426: 但逻辑差不多 各自button也print出各自的值 04/10 02:10
10F:推 tomex: 观念正确,重点是复制保留变数 05/15 07:14