LINQ 标准的查询操作符 转换 ToList()、ToLookup()、ToEnumerable()、ToDictionary、ToType<T>

本章前面提到,查询可以推迟到访问数据项时再执行。

在迭代中使用查询,查询会执行。而使用转换操作符会立即执行查询,把结果放在数组、列表或字典中。

在下面的例子中,调用ToList()扩展方法,立即执行查询,把结果放在List<T>中:

private static void Conversion()
      {
          // query executed immediately
          List<Racer> racers = (from r in Formula1.GetChampions()
                                where r.Starts > 150 //参赛超过150次的选手
                                orderby r.Starts descending
                                select r).ToList(); //注意先括号再使用.ToList()

          foreach (var racer in racers)
          {
              Console.WriteLine("{0} {0:S}", racer);
          }
      }

把返回的对象放在列表中并没有这么简单。

例如,对于集合中从赛车到赛手的快速访问,可以使用新类Lookup<TKey, TElement>。

提示:Dictionary<TKey, TValue>只支持一个键对应一个值。

在System.Linq 命名空间的类Lookup<TKey,TElement>中,一个键可以对应多个值。这些类详见第10 章。

使用复合的from 查询,可以摊平赛手和赛车序列,创建带有Car 和Racer 属性的匿名类型。这句最关键

在返回的Lookup 对象中,键的类型应是表示汽车的string,值的类型应是Racer。

为了进行这个选择,可以给ToLookup()方法的一个重载版本传送一个键和一个元素选择器。

键选择器表示Car 属性,元素选择器表示Racer 属性。

代码的执行顺序是这样的:
private static void Conversion()
        {
            ILookup<string, Racer> racers = (from r in Formula1.GetChampions()//获得每一个赛手
                                             from c in r.Cars //获得赛手的车子集合,遍历是每一个车子多次获得结果
                                             select new
                                             {
                                                 Car = c, //车子名
                                                 Racer = r //这个车手,如果这个车手有多部车子就会出现多个车子名,同一个车手对象的结果,然后
                                             }).ToLookup(cr => cr.Car, cr => cr.Racer);//用车子名做Key,向里面添加车手,如果存在的Key,就会添加,不存在的Key,就建立了Key再添加
                                                  //最后的结果,就是获得了一个以所有车子为Key,对应Value是使用过此车子的车手的集合列表
            if (racers.Contains("Williams")) 
            {
                foreach (var williamsRacer in racers["Williams"])//访问Key是Williams的赛手集合,遍历
                {
                    Console.WriteLine(williamsRacer); // Racer 的 toString(); 方法结果
                }
            }
        }
用 Lookup 类的索引器访问的所有Williams 冠军如下:
Alan Jones
Keke Rosberg
Nigel Mansell
Alain Prost
Damon Hill
Jacques Villeneuve

如果需要在未类型化的集合上使用LINQ 查询,

例如ArrayList,就可以使用Cast()方法,映射成某个类型。

在下面的例子中,基于Object 类型的ArrayList 集合用Racer 对象填充。

为了定义强类型化的查询,可以使用Cast()方法。

private static void Conversion()
        {
            System.Collections.ArrayList list = new System.Collections.ArrayList(Formula1.GetChampions() as System.Collections.ICollection);
            var query = from r in list.Cast<Racer>()
                        where r.Country == "USA"
                        orderby r.Wins descending
                        select r;
            foreach (var racer in query)
            {
                Console.WriteLine("{0:A}", racer);
            }


        }
冯瑞涛
原文地址:https://www.cnblogs.com/finehappy/p/1578828.html