Akl*_*kli 4 c# linq dictionary
我遇到了Linq的一个奇怪的行为:有两个linq表达式可能看起来相同,我有不同的结果!如果我循环一次我得到相同的结果,但在上面它什么都没发现.
这是代码:
Dictionary<String, String> mainDico = new Dictionary<String, String>();
mainDico.Add("key1", "value1");
mainDico.Add("key2", "value2");
List<Dictionary<String, String>> ls = new List<Dictionary<String, String>>();
Dictionary<String, String> fistDico = new Dictionary<String, String>();
fistDico.Add("key1", "value1");
fistDico.Add("key2", "value2");
Dictionary<String, String> secondDico = new Dictionary<String, String>();
secondDico.Add("key1", "other");
secondDico.Add("key2", "other");
ls.Add(fistDico);
ls.Add(secondDico);
IEnumerable<Dictionary<String, String>> failQuery = from p in ls
select p;
IEnumerable<Dictionary<String, String>> successfulQuery = from p in ls
select p;
String[] items = new String[] { "key1","key2" }; // with one element it works
foreach (var item in items)
{
String temp = mainDico[item];
failQuery = failQuery.Where(p => p[item] == temp);
successfulQuery = successfulQuery.Where(p => p[item] == mainDico[item]);
}
Console.WriteLine(successfulQuery.SingleOrDefault() != null);//True
Console.WriteLine(failQuery.SingleOrDefault() != null);//False
Run Code Online (Sandbox Code Playgroud)
问题是你正在关闭循环变量.
有问题的代码部分就在这里:
foreach (var item in items)
{
String temp = mainDico[item];
failQuery = failQuery.Where(p => p[item] == temp);
successfulQuery = successfulQuery.Where(p => p[item] == mainDico[item]);
}
Run Code Online (Sandbox Code Playgroud)
你正在创建一个item在第二种情况下关闭的lambda (也是第一种情况;你应该真的解决这个问题),并且你不会在foreach循环结束之前评估查询; 这意味着它item始终是foreach循环中的最后一项,而不是当前项.这可以通过创建一个新的局部变量来轻松解决,这是你在第一种情况下所做的,这就是为什么这样做的原因.
这是一个相关链接,更详细地讨论了这个问题.(通过搜索"闭环变量"可以找到更多信息.
请注意,这在C#5.0中已更改,因为它经常导致混淆和错误.(这可能是某些人无法重现问题的原因.)
值得注意的是,这与字典无关.在您的查询item中实际上始终是最后一项foreach,而不是当前,这就是它失败的原因.你用item它做的任何东西依赖于它是当前的值不会做你想要的.
| 归档时间: |
|
| 查看次数: |
103 次 |
| 最近记录: |