var numbers = new List<int>(); numbers.Add(1); IEnumerable<int> query = numbers; numbers.Add(2); GridView1.DataSource = query; GridView1.DataBind();
运行结果是: 1,2;
为什么2也会显示出来呢?因为qurey绑定 GridView1时foreach (int n in query),LINQ查询才会执行,这时,数据源numbers已经包含了我们后来添加的元素2,LINQ的这种特性就是延迟执行。
var numbers = new List<int>(); numbers.Add(1); IEnumerable<int> query = numbers; var b=query.Count(); //b的值为1 numbers.Add(2); TextBox1.Text = b.ToString(); GridView1.DataSource = query; GridView1.DataBind();
运行结果是: 1,2; query.Count()的数量为1.因为在执行query.Count()的时候,会执行 query = numbers;到GridView1.DataSource = query;也再会执行一次 query = numbers;
延迟执行带来的一个影响是,当我们重复遍历查询结果时,查询会被重复执行:
var numbers = new List<int>(); numbers.Add(1); IEnumerable<int> query = numbers.ToList(); numbers.Add(2); GridView1.DataSource = query; GridView1.DataBind();
运行结果是:1;可以通过ToArray、ToList、曲线延迟执行
IEnumerable<int> query = new List<int>() { 1,2,3,4,5}; query.Where(a => a != 5); query.Where(a => a != 4); query.Where(a => a != 3); query.Where(a => a != 2); GridView1.DataSource = query; GridView1.DataBind();
运行结果是:1,2,3,4,5;前面的query.Where(a => a != 2)对后面的query没有影响。因为Where(a => a != 2)只对数据进行筛选,而没有改变数据!
总结:LinQ语法,只是构造了“查询语句”,真正执行这种语句的是IEnumerator<T>里的GetEnumerator()方法,因此,当调用GetEnumerator(),就真正执行一次LinQ获取数据,多次调用GetEnumerator(),就多次执行LinQ。这里也解释了,中途修改LinQ(即修改了“查询语句”),下次执行GetEnumerator()方法的结果就会相应地改变了。由于每调用一次GetEnumerator(),就执行一次LinQ,在“查询语句”不变的情况下,就会出现多次重复的查询操作(结果一样),这种情况下,有必要使用ToList(),ToArray()这样的方法把结果固定下来(其实也就是调用GetEnumerator方法返回结果来装载List,Array),然后操作相应的List,Array,避免重复的查询操作。