Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Анонимные типы






В C# предоставляется средство, называемое анонимным типом и связанное непо­ средственно с LINQ. Как подразумевает само название, анонимный тип представляет собой класс, не имеющий имени. Его основное назначение состоит в создании объек­ та, возвращаемого оператором select. Результатом запроса нередко оказывается по­ следовательность объектов, которые составляются из членов, полученных из двух или более источников данных (как, например, в операторе join), или же включают в себя подмножество членов из одного источника данных. Но в любом случае тип возвращае­ мого объекта зачастую требуется только в самом запросе и не используется в остальной части программы. Благодаря анонимному типу в подобных случаях отпадает необхо­ димость объявлять класс, который предназначается только для хранения результата запроса.

Анонимный тип объявляется с помощью следующей общей формы:

new { имя_А = значение_А, имя_В = значение_В,... }

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

new { Count = 10, Max = 100, Min = 0 }

В данном примере создается класс с тремя открытыми только для чтения свойства­ ми: Count, Мах и Min, которым присваиваются значения 10, 100 и 0 соответственно. К этим свойствам можно обращаться по имени из другого кода. Следует заметить, что в анонимном типе используются инициализаторы объектов для установки их полей и свойств в исходное состояние. Как пояснялось в главе 8, инициализаторы объектов обеспечивают инициализацию объекта без явного вызова конструктора. Именно это и требуется для анонимных типов, поскольку явный вызов конструктора для них невоз­ можен. (Напомним, что у конструкторов такое же имя, как и у их класса. Но у аноним­ ного класса нет имени, а значит, и нет возможности вызвать его конструктор.) Итак, у анонимного типа нет имени, и поэтому для обращения к нему приходится использовать неявно типизированную переменную. Это дает компилятору возмож­ ность вывести надлежащий тип. В приведенном ниже примере объявляется перемен­ ная myOb, которой присваивается ссылка на объект, создаваемый в выражении аноним­ ного типа.

var myOb = new { Count = 10, Max = 100, Min = 0 }

Это означает, что следующие операторы считаются вполне допустимыми.

Console.WriteLine(" Счет равен " + myOb.Count);

if(i < = myOb.Max & & i > = myOb.Min) //...

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

Термин анонимный тип не совсем оправдывает свое название. Ведь тип оказывается анонимным только для программирующего, но не для компилятора, который присва­ ивает ему внутреннее имя. Следовательно, анонимные типы не нарушают принятые в C# правила строгого контроля типов.

Для того чтобы стало более понятным особое назначение анонимных типов, рас­ смотрим переделанную версию программы из предыдущего раздела, посвященного оператору join. Напомним, что в этой программе класс Temp требовался для ин­ капсуляции результата, возвращаемого оператором join. Благодаря применению анонимного типа необходимость в этом классе-заполнителе отпадает, а исходный код программы становится менее громоздким. Результат выполнения программы при этом не меняется.

// Использовать анонимный тип для усовершенствования

// программы, демонстрирующей применение оператора join.

using System;

using System.Linq;

 

// Класс, связывающий наименование товара с его порядковым номером.

class Item {

public string Name { get; set; }

public int ItemNumber { get; set; }

 

public Item(string n, int inum) {

Name = n;

ItemNumber = inum;

}

}

 

// Класс, связывающий наименование товара с состоянием его запасов на складе.

class InStockStatus {

public int ItemNumber { get; set; }

public bool InStock { get; set; }

 

public InStockStatus(int n, bool b) {

ItemNumber = n;

InStock = b;

}

}

 

class AnonTypeDemo {

static void Main() {

Item[] items = {

new Item(" Кусачки", 1424),

new Item(" Тиски", 7892),

new Item(" Молоток", 8534),

new Item(" Пила", 6411)

};

 

InStockStatus[] statusList = {

new InStockStatus(1424, true),

new InStockStatus(7892, false),

new InStockStatus(8534, true),

new InStockStatus(6411, true)

};

 

// Сформировать запрос, объединяющий объекты классов Item и

// InStockStatus для составления списка наименований товаров и их

// наличия на складе. Теперь для этой цели используется анонимный тип.

var inStockList = from item in items

join entry in statusList

on item.ItemNumber equals entry.ItemNumber

select new { Name = item.Name,

InStock = entry.InStock };

 

Console.WriteLine(" Товар\tНаличие\n");

 

// Выполнить запрос и вывести его результаты.

foreach(var t in inStockList)

Console.WriteLine(" {0}\t{1}", t.Name, t.InStock);

}

}

Обратите особое внимание на следующий оператор select.

select new { Name = item.Name,

InStock = entry.InStock };

Он возвращает объект анонимного типа с двумя доступными только для чтения свойствами: Name и InStock. Этим свойствам присваиваются наименование товара и состояние его наличия на складе. Благодаря применению анонимного типа необхо­ димость в упоминавшемся выше классе Temp отпадает.

Обратите также внимание на цикл foreach, в котором выполняется запрос. Теперь переменная шага этого цикла объявляется с помощью ключевого слова var. Это не­ обходимо потому, что у типа объекта, хранящегося в переменной inStockList, нет имени. Данная ситуация послужила одной из причин, по которым в C# были внедре­ ны неявно типизированные переменные, поскольку они нужны для поддержки ано­ нимных типов.

Прежде чем продолжить изложение, следует отметить еще один заслуживающий внимания аспект анонимных типов. В некоторых случаях, включая и рассмотренный выше, синтаксис анонимного типа упрощается благодаря применению инициализато­ ра проекции. В данном случае просто указывается имя самого инициализатора. Это имя автоматически становится именем свойства. В качестве примера ниже приведен дру­ гой вариант оператора select из предыдущей программы.

select new { item.Name, entry.InStock };

В данном примере имена свойств остаются такими же, как и прежде, а компилятор автоматически " проецирует" идентификаторы Name и InStock, превращая их в свой­ ства анонимного типа. Этим свойствам присваиваются прежние значения, обозначае­ мые item.Name и entry.InStock соответственно.


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.009 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал