Страница 318 из 502
<b>}</b>
<b>class AnonTypeDemo {</b>
<b> static void Main() {</b>
<b> Item[] items = {</b>
<b> new Item("Кусачки", 1424),</b>
<b> new Item("Тиски", 7892),</b>
<b> new Item("Молоток", 8534),</b>
<b> new Item("
<b> };</b>
<b> InStockStatus[] statusList = {</b>
<b> new InStockStatus(1424, true),</b>
<b> new InStockStatus(7892, false),</b>
<b> new InStockStatus(8534, true),</b>
<b> new InStockStatus (6411, true)</b>
<b> };</b>
<b> // Сформировать запрос, объединяющий объекты классов Item и</b>
<b> // InStockStatus для составления списка наименований товаров и их</b>
<b> // наличия на складе. Теперь для этой цели используется анонимный тип.</b>
<b> var inStockList = from item in items</b>
<b> join entry in statusList</b>
<b> on item.ItemNumber equals entry.ItemNumber</b>
<b> select new { Name = item.Name,</b>
<b> InStock = entry.InStock };</b>
<b> Console.WriteLine ("ТоварtНаличиеn") ;</b>
<b> // Выполнить запрос и вывести его результаты,</b>
<b> foreach(var t in inStockList)</b>
<b> Console.WriteLine("{0}t{1}", t.Name, t.InStock);</b>
<b> }</b>
<b>}</b>
Обратите особое внимание на следующий оператор select.
<b>select new { Name = item.Name,</b>
<b> InStock = entry.InStock };</b>
Он возвращает объект анонимного типа с двумя доступными только для чтения свойствами: Name и InStock. Этим свойствам присваиваются наименование товара и состояние его наличия на складе. Благодаря применению анонимного типа необходимость в упоминавшемся выше классе Temp отпадает.
Обратите также внимание на цикл foreach, в котором выполняется запрос. Теперь переменная шага этого цикла объявляется с помощью ключевого слова var. Это необходимо потому, что у типа объекта, хранящегося в переменной inStockList, нет имени. Данная ситуация послужила одной из причин, по которым в C# были внедрены неявно типизированные переменные, поскольку они нужны для поддержки анонимных типов.
Прежде чем продолжить изложение, следует отметить еще один заслуживающий внимания аспект анонимных типов. В некоторых случаях, включая и рассмотренный выше, синтаксис анонимного типа упрощается благодаря применению инициализатора проекции. В данном случае просто указывается имя самого инициализатора. Это имя автоматически становится именем свойства. В качестве примера ниже приведен другой вариант оператора select из предыдущей программы.
<b>select new { item.Name, entry.InStock };</b>
В данном примере имена свойств остаются такими же, как и прежде, а компилятор автоматически "проецирует" идентификаторы Name и InStock, превращая их в свойства анонимного типа. Этим свойствам присваиваются прежние значения, обозначаемые item.Name и entry.InStock соответственно.
Создание группового объединения
Как пояснялось ранее, оператор into можно использовать вместе с оператором join для создания группового объединения, образующего последовательность, в которой каждый результат состоит из элементов данных из первой последовательности и группы всех совпадающих элементов из второй последовательности. Примеры группового объединения не приводились выше потому, что в этом объединении нередко применяется анонимный тип. Но теперь, когда представлены анонимные типы, можно обратиться к простому примеру группового объединения.
В приведенном ниже примере программы групповое объединение используется для составления списка, в котором различные транспортные средства (автомашины, суда и самолеты) организованы по общим для них категориям транспорта: наземного, морского, воздушного и речного. В этой программе сначала создается класс Transport, связывающий вид транспорта с его классификацией. Затем в методе Main() формируются две входные последовательности. Первая из них представляет собой массив символьных строк, содержащих названия общих категорий транспорта: наземного, морского, воздушного и речного, а вторая — массив объектов типа Transport, инкапсулирующих различные транспортные средства. Полученное в итоге групповое объединение используется для составления списка транспортных средств, организованных по соответствующим категориям.
<b>// Продемонстрировать применение простого группового объединения.</b>
<b>using System;</b>
<b>using System.Linq;</b>
<b>// Этот класс связывает наименование вида транспорта,</b>
<b>// например поезда, с общей классификацией транспорта:</b>
<b>// наземного, морского, воздушного или речного,</b>