c# 闭包探究

闭包: 闭包是能够读取其他函数内部变量的函数

c#的实现是使用lambda表达式

先来尝试一下:

Console.WriteLine("begin");
for(int i=0,j=0;i<10;i++,j++){
		Action action = ()=>{
					Thread.Sleep(10);
					Console.WriteLine("i:"+i+",j:" + j);
				};
		action();
}
Console.WriteLine("end");

输出结果
在这里插入图片描述
在lambda中使用了其他函数的内部变量 i 和 j 实现了闭包。
和我们想象中的一样,输出0-9。

我们再来看个多线程的例子

Console.WriteLine("begin");
for(int i=0,j=0;i<10;i++,j++){
	Action action = ()=>{
					Thread.Sleep(10);
					Console.WriteLine("i:"+i+",j:" + j);
				};
	Task.Factory.StartNew(
					action
	);		
}
Console.WriteLine("end");

输出结果
在这里插入图片描述
看到输出结果是不是心里有点凉凉 ,输出全是10,首先是输出了 begin 和 end,在函数中的i 和 j肯定是10
但是 lambda 表达式中的值 也是 10,那应该有两种可能, 第一种 lambda中的 i 与 函数中的 i 是同一个,
还有一种是 lambda 中的是在 lambda执行的时候取了 函数中的 i的值,因为 lambda 表达式是多线程执行的,它有可能晚了一步执行。

再来看个例子

Console.WriteLine("begin");
for(int i=0,j=0;i<10;i++,j++){
		Action<object> action = (a)=>{
					Thread.Sleep(10);
					Console.WriteLine("i:"+a+",j:" + j);
				};
				
		Task.Factory.StartNew(
					action,i
		);
}
Console.WriteLine("end");

输出结果
在这里插入图片描述
这次我把 i 作为 lambda的一个参数值传递,这时候 i在我们的意料之中0-9都有,顺序不一致是因为多线程执行顺序有先有后。

再来个单线程的

int i = 0;
int j = 0;
Action action = 
					()=>{
						Thread.Sleep(10);
						Console.WriteLine("i:"+i+",j:" + j);
						i++;
};
			
action();		
i = 20;
Console.WriteLine("ii:" + i + ",jj:" + j);
			
action();
Console.WriteLine("ii:" + i + ",jj:" + j);

输出结果
在这里插入图片描述
这次可以看出,闭包中修改的值影响到了函数本身内部变量的值,函数本身变量的值的修改也影响到了闭包的值,那应该就是 闭包中的值和函数本身的值是同一个。

翻阅了几篇文章发现闭包被编译成了一个类。

拿最后一个例子来举例,会被编译成类似以下代码:

class TmpClass{
			public int i;
			public int j;
			public void method(){
				Thread.Sleep(10);
				Console.WriteLine("i:"+i+",j:" + j);
				i++;
			}
		}
		
		static void Procedure(){
			TmpClass tmpclass = new TmpClass{
				i=0,
				j=0
			};
			
			tmpclass.method();
			
			tmpclass.i = 20;
			Console.WriteLine("ii:" + tmpclass.i + ",jj:" + tmpclass.j);
			
			tmpclass.method();
			
			Console.WriteLine("ii:" + tmpclass.i + ",jj:" + tmpclass.j);
		}

lambda 表达式在多线程中使用外部函数内部变量,值类型最好还是使用参数传递,不容易出错。引用类型最好还是不要这么用吧!当然看实际情况。好吧,我又一堆代码需要重新调整啦。知识点还是得学习的深入一点。少吃点亏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值