Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

7.16.2.5Предложения select

Выражение запроса вида

from x in e select v

переводится в

( e ) . Select ( x => v )

за исключением случая, когда v является идентификатором x, тогда перевод имеет вид просто

( e )

Например

from c in customers.Where(c => c.City == “London”) select c

переводится просто в

customers.Where(c => c.City == “London”)

7.16.2.6Предложения groupby

Выражение запроса вида

from x in e group v by k

переводится в

( e ) . GroupBy ( x => k , x => v )

за исключением случая, когда v является идентификатором x, тогда перевод имеет вид

( e ) . GroupBy ( x => k )

В примере

from c in customers group c.Name by c.Country

переводится в

customers. GroupBy(c => c.Country, c => c.Name)

7.16.2.7Прозрачные идентификаторы

При некоторых переводах вставляются переменные диапазона с прозрачными идентификаторами, обозначенными *. Прозрачные идентификаторы не являются правильным языковым средством, они существуют только в виде промежуточного этапа в процессе перевода выражений запросов.

Когда при переводе запроса вставляется прозрачный идентификатор, дальнейшие этапы перевода распространяют прозрачный идентификатор в анонимные функции и анонимные инициализаторы объектов. В таких контекстах прозрачные идентификаторы функционируют следующим образом.

  • Когда прозрачный идентификатор является параметром анонимной функции, члены связанного анонимного типа автоматически оказываются в области действия в теле анонимной функции.

  • Когда член с прозрачным идентификатором находится в области действия, члены этого члена также находятся в области действия.

  • Когда прозрачный идентификатор оказывается в роли декларатора члена в инициализаторе анонимного объекта, он создает член с прозрачным идентификатором.

На этапах перевода, описанных выше, прозрачные идентификаторы всегда создаются вместе с анонимными типами с намерением сохранить несколько переменных диапазона в виде членов одного объекта. В реализации C# для группирования нескольких переменных диапазона можно использовать механизм, отличный от анонимных типов. В следующих примерах перевода предполагается использование анонимных типов и показывается, как при переводе можно избавиться от прозрачных идентификаторов.

В примере

from c in customers from o in c.Orders orderby o.Total descending select new { c.Name, o.Total }

переводится в

from * in customers. SelectMany(c => c.Orders, (c,o) => new { c, o }) orderby o.Total descending select new { c.Name, o.Total }

и далее переводится в

customers. SelectMany(c => c.Orders, (c,o) => new { c, o }). OrderByDescending(* => o.Total). Select(* => new { c.Name, o.Total })

что после удаления прозрачных идентификаторов эквивалентно

customers. SelectMany(c => c.Orders, (c,o) => new { c, o }). OrderByDescending(x => x.o.Total). Select(x => new { x.c.Name, x.o.Total })

где x — идентификатор, созданный компилятором, который в других условиях является невидимым и недоступным.

В примере

from c in customers join o in orders on c.CustomerID equals o.CustomerID join d in details on o.OrderID equals d.OrderID join p in products on d.ProductID equals p.ProductID select new { c.Name, o.OrderDate, p.ProductName }

переводится в

from * in customers. Join(orders, c => c.CustomerID, o => o.CustomerID, (c, o) => new { c, o }) join d in details on o.OrderID equals d.OrderID join p in products on d.ProductID equals p.ProductID select new { c.Name, o.OrderDate, p.ProductName }

что дальше сокращается до

customers. Join(orders, c => c.CustomerID, o => o.CustomerID, (c, o) => new { c, o }). Join(details, * => o.OrderID, d => d.OrderID, (*, d) => new { *, d }). Join(products, * => d.ProductID, p => p.ProductID, (*, p) => new { *, p }). Select(* => new { c.Name, o.OrderDate, p.ProductName })

конечный перевод имеет вид

customers. Join(orders, c => c.CustomerID, o => o.CustomerID, (c, o) => new { c, o }). Join(details, x => x.o.OrderID, d => d.OrderID, (x, d) => new { x, d }). Join(products, y => y.d.ProductID, p => p.ProductID, (y, p) => new { y, p }). Select(z => new { z.y.x.c.Name, z.y.x.o.OrderDate, z.p.ProductName })

где x, y и z — идентификаторы, созданные компилятором, которые в других условиях являются невидимыми и недоступными.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]