c# - 为什么这两个 c# 脚本给出不同的结果?
问题描述
我正在处理一个大的按钮列表,并尝试AddListener()
使用快速的方式为该列表中的每个按钮
第一种方法是
btn[0] = CHbutt[0].GetComponent<Button>(); btn[0].onClick.AddListener(delegate { CH(0); });
btn[1] = CHbutt[1].GetComponent<Button>(); btn[1].onClick.AddListener(delegate { CH(1); });
btn[2] = CHbutt[2].GetComponent<Button>(); btn[2].onClick.AddListener(delegate { CH(2); });
btn[3] = CHbutt[3].GetComponent<Button>(); btn[3].onClick.AddListener(delegate { CH(3); });
它工作得很好,AddListener()
对所有按钮都有效btn[]
;但是很多行...
第二种方式
for (int i = 0; i < CHmatt.Count; i++)
{
btn[i] = CHbutt[i].GetComponent<Button>(); btn[i].onClick.AddListener(delegate { CH(i); });
}
但是这个不起作用,这个AddListener()
只有最后一个按钮btn[0]
我很好奇这两个脚本之间的区别。
解决方案
这是一个捕获问题。更改代码如下,以避免捕获i
:
for (int i = 0; i < CHmatt.Count; i++)
{
var ii = i;
btn[i] = CHbutt[i].GetComponent<Button>();
btn[i].onClick.AddListener(delegate { CH(ii); });
}
传递给AddListener
函数的是一个delegate
方法;但是,由于您传递的是循环迭代变量i
,因此会捕获上下文并i
实际引用。随着循环的推进,所有捕获i
的值都会发生变化,因此使这种方法“不起作用”。
通过引入一个本地副本i
(这里名字不重要,我叫它ii
),它在每次循环迭代时都超出范围,i
避免了捕获,并将实际值ii
传递给delegate
方法(技术上,捕获,但它是每个循环迭代的副本i
,因此不会随着更改而i
更改。)
推荐阅读
- python - 如何在 Scrapy 上实现自定义代理?
- python - Python函数内部函数访问全局变量
- php - 如何在php中读取包含合并单元格的excel文件?
- javascript - http_only = false 时不在 document.cookie 列表中的 cookie
- mysql - 很难根据允许的最大连接数正确设置 RAILS_MAX_THREADS
- shopware - 如何在 Shopware 5 的 Enlight_Event_EventArgs 对象订阅者中执行重定向?
- javascript - 限制 Loopback 4 查询中属性的长度数组类型?
- python - 以数字方式查找正根
- c++ - 如何使用移动构造函数释放内存
- postgresql - Postgresql 9.3 忽略 pgpass.conf 文件