Как выполнить проекцию анонимного типа
В некоторых случаях может потребоваться проецировать запрос на новый тип, даже если известно, что этот тип будет использоваться недолго. Создание нового типа для использования в проекции требует много дополнительной работы. Гораздо более эффективный подход заключается в проецировании на анонимный тип. Анонимные типы позволяют определять класс и инициализировать его объект, не присваивая имя этому классу.
Анонимные типы являются реализацией в языке C# математического понятия кортежа. Математический термин «кортеж» обозначает одноэлементные, двухэлементные, трехэлементные, четырехэлементные, пятиэлементные и n-элементные последовательности. Он относится к конечной последовательности объектов, каждый из которых имеет конкретный тип. Иногда такую последовательность называют списком пар «имя/значение». Например, содержимое адреса в XML-документе Типичный заказ на покупку можно представить следующим образом.
Name: Ellen Adams
Street: 123 Maple Street
City: Mill Valley
State: CA
Zip: 90952
Country: USA
Создание экземпляра анонимного типа удобно трактовать как создание n-элементного кортежа. При написании запроса, создающего кортеж в предложении select, запрос возвращает объект IEnumerable кортежа.
Пример
В этом примере предложение select проецирует анонимный тип. Затем в этом примере используется тип var для создания объекта IEnumerable. В цикле foreach переменная итерации становится экземпляром анонимного типа, созданного в выражении запроса.
В этом примере используется следующий XML-документ: Образец XML-файла. Заказчики и заказы (LINQ to XML).
XElement custOrd = XElement.Load("CustomersOrders.xml");
var custList =
from el in custOrd.Element("Customers").Elements("Customer")
select new {
CustomerID = (string)el.Attribute("CustomerID"),
CompanyName = (string)el.Element("CompanyName"),
ContactName = (string)el.Element("ContactName")
};
foreach (var cust in custList)
Console.WriteLine("{0}:{1}:{2}", cust.CustomerID, cust.CompanyName, cust.ContactName);
Dim custOrd As XElement = XElement.Load("CustomersOrders.xml")
Dim custList = _
From el In custOrd.<Customers>.<Customer> _
Select New With { _
.CustomerID = el.@<CustomerID>, _
.CompanyName = el.<CompanyName>.Value, _
.ContactName = el.<ContactName>.Value _
}
For Each cust In custList
Console.WriteLine("{0}:{1}:{2}", cust.CustomerID, cust.CompanyName, cust.ContactName)
Next
Этот код выводит следующие результаты.
GREAL:Great Lakes Food Market:Howard Snyder
HUNGC:Hungry Coyote Import Store:Yoshi Latimer
LAZYK:Lazy K Kountry Store:John Steel
LETSS:Let's Stop N Shop:Jaime Yorres