LINQ(转换操作符)

前面提到,查询可以推迟到访问数据项时再执行。在迭代使用查询时,查询会执行。而使用转换操作符会立即执行查询,把查询结果放在数组、列表或字典中。

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

        static void ToList()
        {
            List<Racer> racers = (from r in Formula1.GetChampions()
                       where r.Starts > 100
                       orderby r.Starts descending
                       select r).ToList();
            foreach(var racer in racers)
            {
                System.Console.WriteLine($"{racer.ToString()} {racer:S}");
            }
        }

查询结果显示如下:

Graham Hill 176
Jack Brabham 125
Denny Hulme 112
John Surtees 111

把返回的对象放在列表中并没有这么简单。例如,对于集合类从赛车到赛车手的快速访问,可以使用新类Lookup<TKey,TElement>。

注:Dictionary<TKey,TValue>类只支持一个键对应一个值。在System.Linq名称空间的类Lookup<TKey,TElement>类中,一个键而可以对应多个值。

使用复合的from查询,可以摊平赛车手和赛车序列,创建带有Car和Racer属性的匿名类型。在返回的Lookup对象中,键的类型应是表示汽车的string,值的类型应是Racer。为了进行这个选择,可以给ToLookup()方法的一个重载版本传递一个键和一个元素选择器。键选择器引用Car属性,元素选择器引用Racer属性:

        static void ToLookup()
        {
            var racers = (from r in Formula1.GetChampions()
                       from c in r.Cars
                       select new {
                           Car = c,
                           Racer = r
                       }).ToLookup(rc=>rc.Car,rc=>rc.Racer);
            if(racers.Contains("Ferrari"))
            {
                foreach(var ferrariRacer in racers["Ferrari"])
                {
                    System.Console.WriteLine(ferrariRacer.ToString());
                }
            }
        }

用Lookup类的索引器访问的所有"Ferrari"冠军,结果如下:

Alberto Ascari
Juan Manuel Fangio
Mike Hawthorn
Phil Hill
John Surtees

如果需要在非类型化的集合上(如ArrayList)使用LINQ查询,就可以使用Cast()方法。在下面的例子中,基于Object类型的ArrayList集合用Race对象填充。为定义强类型化的查询,可使用Cast()方法:

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

结果仅包含来自意大利的一级方程式冠军:

Alberto,Ascari,Italy; starts:32, wins:10
Nino,Farina,Italy; starts:33, wins:5

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值