⼀个需要注意的地⽅看下⾯的代码:
using System;
using System.Collections.Generic;using System.Linq;
namespace MyCsStudy{
class Program {
static void Main(string[] args) {
List list.Add(() => i); //list依次添加0,1,2?? } foreach (var item in list) { Console.WriteLine(item()); //输出的竟然是? } } }} 运⾏试⼀下看看结果,如果你以前碰到过js⾥的问题,相信你不会⼤惊⼩怪(⽽且可能已经知道了问题的原因),但是,如果你从来没有碰到过这种情况,是不是令你⼤吃⼀惊?!输出的竟然不是0,1,2,⽽是三个3,oh,my god。紧接着,⽴刻,你会⼤胆想到这⾥的list在Add⽅法执⾏的地⽅Add进去的是⼀个引⽤类型(这⾥是lambda表达式()=>i),它们执⾏的结果共同指向值为3的同⼀个引⽤地址!没错,我们详细分析⼀下: 1、我们⾸先定义⼀个list,其存储格式为func 2、因为lambda表达式实质就是个委托,也就指向⼀个匿名函数,所以,在foreach输出的时候,使⽤item()来调⽤它,让它所指向的函数执⾏。 ⾄于第2步中item()执⾏的结果为什么都是3,原因是这样的: (1)在for循环中,只能有⼀个 i 变量。即在第⼀次循环时,i 的地址就分配好了(注意了,这⾥i的地址第⼀次分配后是不变的),不会因为循环次数的多少⽽发⽣任何改变,其改变的只能是⾥⾯装载的值。 (2)lambda表达式在构造时, 传进去的是变量的地址,⽽不是具体值。只有当真正执⾏这个lambda表达式时,才会去确定它的值。这就是为什么上⾯的例⼦中,其结果均为3(for循环在最后,当i=2时,i⼜加了1)。那么如何解决这个问题?解决⽅案很简单: 1是在for循环中,定义⼀临时变量tmpNum,存储i的值即可。因为编译器会对该临时变量重新分配内存,这样,每次循环,都重新分配新的内存,就不会有这个问题了。2⽤foreach也是同样的道理 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- huatuowenda.com 版权所有 湘ICP备2023022495号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务