循环中的Union
前几天同事遇到这样一个问题。在循环中使用了Union,但最后的结果和预期的不一样。
下面的代码仅为问题的重现,没有实际意义
View Code
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 var list = new[] { 1, 2, 3, 4, 5 };
6 var first = list.Where(l => l == 1);
7 foreach (var li in list)
8 {
9 first = first.Union(list.Where(l => l == li));
10 }
11
12 first.ToList().ForEach(l => Console.Write("{0}\t", l));
13 Console.WriteLine();
14 }
15 }
2 {
3 static void Main(string[] args)
4 {
5 var list = new[] { 1, 2, 3, 4, 5 };
6 var first = list.Where(l => l == 1);
7 foreach (var li in list)
8 {
9 first = first.Union(list.Where(l => l == li));
10 }
11
12 first.ToList().ForEach(l => Console.Write("{0}\t", l));
13 Console.WriteLine();
14 }
15 }
以下是结果:
预期的结果应该是:1 2 3 4 5
为什么实际的结果和预期的结果不同呢?
我们对代码进行了如下修改:
View Code
class Program
{
static void Main(string[] args)
{
var list = new[] { 1, 2, 3, 4, 5 };
var first = list.Where(l => l == 1);
foreach (var li in list)
{
// 原代码
// first = first.Union(list.Where(l => l == li));
// 修改后的代码
first = first.Union(list.Where(l => l == li).ToList());
}
first.ToList().ForEach(l => Console.Write("{0}\t", l));
Console.WriteLine();
}
}
{
static void Main(string[] args)
{
var list = new[] { 1, 2, 3, 4, 5 };
var first = list.Where(l => l == 1);
foreach (var li in list)
{
// 原代码
// first = first.Union(list.Where(l => l == li));
// 修改后的代码
first = first.Union(list.Where(l => l == li).ToList());
}
first.ToList().ForEach(l => Console.Write("{0}\t", l));
Console.WriteLine();
}
}
以下是结果:
这次结果和预期相同。
这两次的不同之处就在于,在第二次中对查询通过调用ToList()方法进行了立即执行。
在一次的查询过程中,只拼接了查询,而在变量first.ToList()时才执行了查询,执行查询需要用到变量li,而最后li的值为5。所以最终结果也就成了1 5,而不是开始预期的1 2 3 4 5.
总结,所以在使用Linq时一定要小心,有些时候可能你就用错了。
qishichang