项目场景:某项目综合查询功能。
例如:项目场景:示例:通过蓝牙芯片(HC-05)与手机 APP 通信,每隔 5s 传输一批传感器数据(不是很大)
问题描述
先来看原代码:
这段代码看似没有什么问题,但是在运行的时候会报一个错误:“索引超出了数组界限······”,然后当我断点调试的时候,发现循环里的i的值竟然是等于N的,怪不得会说超出数组界限。
原因分析:
这段代码涉及到了一个情况:闭包。
闭包(Closure)是词法闭包的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。
闭包的概念来源于python,但并不是python特有。在C#中,闭包是这样定义的:内层的函数可以引用包含在它外层的函数的变量,即使外层函数的执行已经终止。但该变量提供的值并非变量创建时的值,而是在父函数范围内的最终值。
在结合上面的代码可以很清楚的理解这段含义,循环里的代码使用了委托和lambda函数,所以当循环中的Lambda表达式被真正执行的时候,取的i并不是当次循环的值,而是循环结束后的值,即是i = N,所以才会报错
解决方案:
这时候只要我们加上临时变量a,让Lambda表达式中的委托取临时变量的值,即可避免这种BUG发生。如图:
这样lambda函数每次取的索引值就是当次的循环值。
结论:
当在循环中使用委托和lambda函数时,并且引用了循环中的值时,要注意闭包的影响,可能会产生一些意料之外的BUG。