C# 匿名回调方法在循环体中使用的注意事项
今天在做AVG工具的选择分支功能时发现了一个问题,先把代码贴上来:
private void SelectionParse(string value)
{
string[] ss = value.Split('|');
List<GameObject> s_inss = new List<GameObject>(); view.selection.SetActive(true); for (int i = ; i < ss.Length; i++)
{
string sc = ss[i].Split('@')[];
string sid = ss[i].Split('@')[]; var ins = Instantiate(view.s_itemPrefab, view.selection.transform); s_inss.Add(ins); ins.GetComponentInChildren<Text>().text = sc;
int si = i;
ins.GetComponent<Button>().onClick.AddListener(() =>
{
Debug.Log(i);
Debug.Log(si);
int id = int.Parse(sid);
view.AddLogText("", sc);
JumpToIDLine(id);
foreach (var s_ins in s_inss)
{
s_ins.GetComponent<Button>().onClick.RemoveAllListeners();
Destroy(s_ins);
}
view.selection.SetActive(false);
});
}
}
上面的代码中,i和si打印的结果是不同的:
如果我们直接在匿名回调方法中使用循环体中的增值变量i,得到的永远是固定的值,在上面的代码中也即是ss.Length的值。
然而很多时候我们需要的是当时的循环变量值,虽然在回调方法执行的时候这个循环体早已执行完成,但我们可以通过在循环体内回调方法外单独存储一个循环增量i的值,也即是上面的si,这样在后面的方法回调时便可以按照当时的增量i(也就是si)来取值。
总结就是:
si=循环体循环时增量i的值。
至于这个现象产生的原因,查阅后发现是因为C#后台为我们在回调方法执行之前就提前存储了该回调方法使用的外部变量。(感觉跟协程的挂起有点像)
也得益于这样的机制,在一些方法内部书写回调方法可以使一些复杂的逻辑极快的实现完成,避免了重复的传递参数和记录全局变量。
例如上面的短短几句话就实现了:
解析选项的文本内容,显示选项选单,根据选项数量创建对应个数的选项克隆,给克隆的对象添加文本内容和按钮监听,当这个按钮被按下时将选项对应的文本内容输出到Log中,执行跳转到选项对应id的文本位置,同时移除所有选项的按钮监听,销毁其余所有选项,并隐藏选项选单。一个完美的循环!
最重要的是这些只需要在一个方法中完成,这确实是令人兴奋的事。
C# 匿名回调方法在循环体中使用的注意事项的更多相关文章
- Java回调方法详解
回调在维基百科中定义为: 在计算机程序设计中,回调函数,是指通过函数参数传递到其他代码的,某一块可执行代码的引用. 其目的是允许底层代码调用在高层定义的子程序. 举个例子可能更明白一些:以Androi ...
- javascript 利用匿名函数对象给你异步回调方法传参数
先来创建一个匿名函数对象: /*** * 匿名函数 */ var callChangeBtn=new function(bugBtn){ this.chage=function(json){ bugB ...
- android中 回调方法,怎么转变为阻塞执行的方法
项目中需要用到在wifi这一块,扫描附近wifi,然后一个个遍历所有wifi,并且尝试连接,所以就在这里需要每连接一个wifi进行阻塞,当连接失败的时候才进行尝试下一个连接,当连接成功时则break. ...
- Android中的广播基本实现及回调方法的理解
在Android中broadcast这一节的内容其实不算多主要是牵扯到一个broadcastreceiver类,这个类是一个抽象类,下面有一个抽象方法onreceiver(),可以再我们收到网络状态变 ...
- ruby中的回调方法和钩子方法
在ruby中,当某些特定的事件发生时,将调用回调方法和钩子方法.事件有如下几种: 调用一个不存在的对象方法 类混含一个模块 定义类的子类 给类添加一个实例方法 给对象添加一个单例方法 引用一个不存在的 ...
- iOS开发之swift与OC混编出现的坑,oc中不能对swift的代理进行调用,不能访问swift中的代理,swift中的回调方法
1. Swift与oc混编译具体怎么实现,这儿我就不重复讲出了,网上有大把的人讲解. 2. 在swift与OC混编的编译环境下, oc类不能访问swift创建类中的代理? 解决方法如下: 在代理的头部 ...
- Vue界面中关于APP端回调方法问题
在混合开发中,HTML界面经常性的需要调用APP端提供的原生方法,而且在很多时候,APP端需要各种回调,如果将所有的回调方法写在内部,不是很方便,而且有些时候,APP端需要定义一些主动触发HTML界面 ...
- JS中的匿名函数、回调函数、匿名回调函数
工欲善其事必先利其器 在学习JavaScript设计模式一书时,遇到了“匿名回调函数”这个概念,有点疑惑,查找了些资料重新看了下函数的相关知识点之后,对这个概念有了认识.九层之台,起于垒土.在熟悉这一 ...
- Android事件侦听器回调方法浅谈
http://developer.51cto.com/art/201001/180846.htm Android事件侦听器作为视图View类的接口,其中包含有不少回调方法,比如:onClick():o ...
随机推荐
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 11
23.6 使用第三方接口服务实例 接供服务的第三方接口平台有很多,现在的项目中也经常用到一些第三方接口,如支付宝.微信.短信.邮件接口等,我们需要借助第三方的能力来实现产品的某些功能.如果自己已经掌 ...
- selenium三大切换的骚操作之显性等待
一.handle窗口切换 当点击某个元素后,会重新生成一个新的页签,但此时我们的操作仍然在原先的窗口当中,如果要在新的窗口继续操作元素,那么就要用到handle窗口切换的方法. 常用方法: windo ...
- Have a look ^_^
参考书籍: <重构 改善既有代码的设计 第2版>马丁 福勒著 人民邮电出版社 马丁 福勒的其他著作:<分析模式>,<UML精粹>,<领域特定语言> 目录 ...
- 依赖注入在 dotnet core 中实现与使用:3 使用 Lazy<T> 延迟实例化
有些对象我们并不想一开始就实例化,由于性能或者功能的考虑,希望等到使用的时候再实例化.考虑存在一个类 A, 它使用了依赖的类 B,在 A 中,只有某些不常用到的方法会涉及调用 B 中的方法,多数情况下 ...
- MongoDB for OPS 03:分片 shard 集群
写在前面的话 上一节的复制集也就是主从能够解决我们高可用和数据安全性问题,但是无法解决我们的性能瓶颈问题.所以针对性能瓶颈,我们需要采用分布式架构,也就是分片集群,sharding cluster! ...
- WPF图片,DataGrid等实现圆角
<Grid HorizontalAlignment="Center" VerticalAlignment="Center"> <Grid.Ro ...
- WeTest全球化服务,为使命召唤手游质量保驾护航
导读 使命召唤系列作为经典FPS游戏,以良好的表现与出色的射击手感,颠覆了玩家对传统第一人称射击的传统观念.同名手游(CODM)10月份在海外上线,仅一周内下载量就已突破一亿次,更是横扫139个国家及 ...
- arcgis api for javascript 学习(六) 地图打印
1.本文应用arcgis api for javascript对发布的动态地图进行打印,打印的为PDF格式,打印出来如图: 2.需要特别注意的是:我们在运行代码前,需要打开PrintingTools, ...
- 微信小程序动画之弹出菜单
用微信小程序做了一个动画,效果如上图: 代码: js: Page({ data: { isPopping: false, animPlus: {}, animCollect: {}, animTran ...
- 4.智能快递柜(通信篇-SOCKET)
1.智能快递柜(开篇) 2.智能快递柜(终端篇) 3.智能快递柜(通信篇-HTTP) 4.智能快递柜(通信篇-SOCKET) 5.智能快递柜(通信篇-Server程序) 6.智能快递柜(平台篇) 7. ...