Visual C#中IEnumerable数组循环填充后数据消失原因咨询
为什么填充的IEnumerable数组数据在离开循环后消失?
嗨,这个问题我之前踩过同款坑,本质是LINQ的延迟执行特性在搞鬼!
你在循环里给drs[i]赋值的并不是实际的数据集合,而是一个LINQ查询表达式。LINQ默认是延迟执行的——简单说就是,它不会在你写查询的时候就去DataTable里捞数据,而是要等到你真正去枚举它的时候(比如用foreach遍历、调用ToList()/ToArray()这类方法),才会实际执行查询逻辑。
更关键的是,你的循环变量i是被所有查询共享的引用。当循环结束后,i的值已经变成了5(因为循环条件是i<5,最后一次循环后i会自增到5才退出)。这时候当你去访问drs里的任意一个查询时,它会用当前的i=5来执行where条件,而你的DataTable里显然没有ID为5的数据,所以看起来就像是之前填充的数据全部“消失”了。
给你两个实用的解决办法:
办法一:捕获当前循环的变量值
在循环内部创建一个局部变量,把当前的i值存下来,让每个查询绑定到这个局部变量,而不是共享的循环变量i:
for(int i=0;i<5;i++) { int currentId = i; // 捕获当前循环的i值,每个循环都会创建新的currentId drs[i]= from x in dt.AsEnumerable() where x["ID"].ToString() == currentId.ToString() select x; }
这样每个查询都会使用对应循环次数的currentId值,后续枚举的时候就能得到正确的结果。
办法二:立即执行查询
把LINQ查询转换成实际的集合(比如List<DataRow>),强制查询在循环内部就执行完毕,把数据存下来:
for(int i=0;i<5;i++) { drs[i]= (from x in dt.AsEnumerable() where x["ID"].ToString() == i.ToString() select x).ToList(); // 用ToArray()也可以,只要是能触发立即执行的方法 }
这时候drs[i]保存的是已经从DataTable里取出来的数据,而不是延迟执行的查询,离开循环后数据自然不会“消失”。
简单总结下:延迟执行让查询一直“记住”外部变量i的引用,而不是它的值,循环结束后i的值变了,查询结果也就不对了。要么捕获变量值,要么立即执行查询,就能解决这个问题。
内容的提问来源于stack exchange,提问作者Pikachu620
相关产品推荐
相关产品推荐

