В ней пропущено описание типа. Этим типом мог быть класс Customer, если бы такой класс был объявлен ранее. Но его нет. Так как extension-метод Select (или запрос) требует выбрать только два поля из пяти, указанных в инициализаторе объекта, то говорят, что объекты проецируются на кортеж (c.LastName, c.Addr).
Термин кортеж принят в нашей литературе по дискретной математике. В англоязычной литературе используют термин tuple, который имеет тот же смысл: упорядоченная последовательность полей. Иногда говорят n-tuple. В некоторых наших изданиях используют термин "n-ка" (энка — последовательность из n элементов).
При обработке запроса компилятор создает объекты типа <Anonymous Type>. Вы можете увидеть этот тип в окне отладчика Autos при пошаговом выполнении кода. Найдите в этом окне, какой тип компилятор вывел (infered) для самого запроса (объекта query). Описание этого типа выглядит так.
Enumerable.WhereSelectArrayIterator<<>f__AnonymousType1<string,string,string,string,string>,
<>f__AnonymousType2<string,string>> . . .
Теперь вам должно быть понятно, для чего в язык C# добавили описатель var. Этот короткий описатель способен заменить любой из временно создаваемых компилятором типов. Временные типы, как видите, могут иметь ужасающий вид.
В пространстве имен System описан generic-делегат (то есть, делегатный тип) Predicate<>. Он определяет сигнатуру bool Predicate<T>(T). Переменная этого типа способна указывать на любую функцию, которая требует параметр произволного типа T и возвращает true или false. Покажем, как использовать предикат для вызова extension-метода FindAll. Последний работает с входной последовательностью и возвращает выходную последовательность, каждый элемент которой удовлетворяет условию, заданному предикатом.
Console.WriteLine("\nTest FindAll for Array");
Action<int> print = c => Console.Write(c + ", ");
int[] fib = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 }; // Ряд чисел Fibonacci
Predicate<int> pred = c => c % 2 == 1;
Array.ForEach<int> (Array.FindAll<int>(fib, pred), print);
¨ Работа ведется с массивом целых чисел.
¨ Generic-делегат print на лету создает функцию, которая выводит в консольное окно свой параметр.
¨ Generic-делегат pred создает функцию, возвращающую результат проверки своего аргумента на нечетность.
¨ Extension generic-метод FindAll пробегает по последовательности, заданной первым аргументом (fib), и применяет к каждому ее элементу метод, заданный делегатом print.
¨ Extension generic-метод ForEach пробегает по последовательности, заданной первым аргументом, и применяет к каждому ее элементу метод, заданный делегатом pred.
Необходимо научиться правильно называть новые реалии и операции, производимые с ними. Для практики повторим логику происходящего другими словами.
¨ Предикат pred, имеющий тип Predicate<int> (он же является делегатом), задан λ-выражением. Он позволяет отобрать нечетные числа из последовательности Fibonacci, возвращаемой extension-методом FindAll.
¨ Делегат print типа Action<int> также задан задан λ-выражением, которое воздействует на каждый элемент последовательности, возвращаемой extension-методом ForEach.
Следующий пример производит те же действия, но с generic-списком типа List<int>. Обратите внимание на то, что синтаксис работы с типизированным списком проще.
Console.WriteLine("\nTest FindAll for List<int>");
List<int> list = new List<int>(fib);
list.FindAll(predicate).ForEach(print);
Класс Enumerable имеет множество статических методов для выполнения запросов к последовательностям (коллекцям, реализующим интерфейс IEnumerable<T>). В то же время класс Queryable имеет множество статических методов для выполнения запросов к структурам данных, реализующим интерфейс IQueryable <T>. Эти методы (операции) разбиты на 14 категорий (групп). Следующая таблица отображает эту классификацию.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.