Возможности C#, поддерживающие LINQ

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

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

Выражения запросов используют декларативный синтаксис, аналогичный SQL или XQuery, для выполнения запросов к коллекциям IEnumerable. Во время компиляции синтаксис запроса преобразуется в вызовы методов к реализации методов расширения стандартных операторов запросов поставщиком LINQ. Приложения управляют стандартными операторами запросов в области, указывая соответствующее пространство имен с помощью директивы using. Следующее выражение запроса принимает массив строк, группирует их в соответствии с первым символом в строке и упорядочивает группы.

var query = from str in stringArray
            group str by str[0] into stringGroup
            orderby stringGroup.Key
            select stringGroup;

Дополнительные сведения см. в разделе Выражения запросов LINQ.

Неявно типизированные переменные (var)

Вместо явного задания типа при объявлении и инициализации переменной можно использовать модификатор var, чтобы сообщить компилятору о необходимости определить и присвоить тип, как показано ниже:

var number = 5;
var name = "Virginia";
var query = from str in stringArray
            where str[0] == 'm'
            select str;

Переменные, объявленные как var, так же строго типизированы, как и переменные, тип которых задается явно. Использование var делает возможным создание анонимных типов, однако его можно использовать только для локальных переменных. Массивы также могут быть объявлены путем неявной типизации.

Дополнительные сведения см. в статье Неявно типизированные локальные переменные (руководство по программированию на C#).

Инициализаторы объектов и коллекций

Инициализаторы объектов и коллекций позволяют инициализировать объекты без явного вызова конструктора для объекта. Инициализаторы обычно используются в выражениях запросов при проецировании исходных данных в новый тип данных. При наличии, например, класса с именем Customer с общедоступными свойствами Name и Phone инициализатор объектов можно использовать как в следующем примере кода:

var cust = new Customer { Name = "Mike", Phone = "555-1212" };

Продолжим рассматривать класс Customer. Предположим, что есть источник данных с именем IncomingOrders и что для каждого заказа с большим значением OrderSize нужно создавать класс Customer на основе этого заказа. Можно выполнить запрос LINQ для этого источника данных и использовать инициализацию объекта, чтобы заполнить коллекцию:

var newLargeOrderCustomers = from o in IncomingOrders
                            where o.OrderSize > 5
                            select new Customer { Name = o.Name, Phone = o.Phone };

У источника данных может быть больше скрытых свойств, чем у класса Customer, такого как OrderSize. Но инициализация объекта позволяет преобразовать данные, возвращаемые по запросу, в требуемый тип. Мы выберем данные, соответствующие нашему классу. В результате мы заполнили IEnumerable новыми классами Customer, как и требовалось. Приведенный выше код также можно представить в синтаксисе метода LINQ:

var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name = y.Name, Phone = y.Phone });

Дополнительные сведения можно найти в разделе

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

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

select new {name = cust.Name, phone = cust.Phone};

Дополнительные сведения см. в статье Анонимные типы.

Методы расширения

Метод расширения представляет собой статический метод, который может быть связан с типом, чтобы его можно было вызывать, как если бы он являлся методом экземпляра типа. Эта возможность позволяет, по сути, "добавлять" новые методы в существующие типы, фактически не изменяя их. Стандартные операторы запросов — это набор методов расширения, предоставляющий функции запросов LINQ для любого типа, реализующего IEnumerable<T>.

Дополнительные сведения см. в разделе Методы расширения.

Лямбда-выражения

Лямбда-выражение — это встроенная функция, которая использует оператор => для отделения входных параметров от тела функции. Она может быть преобразована во время компиляции в делегат или дерево выражения. В программировании LINQ вы столкнетесь с лямбда-выражениями при выполнении прямых вызовов к стандартным операторам запросов.

Дополнительные сведения см. в разделе:

См. также