Checked и unchecked 14 страница
В примере using System; delegate void D(); class Test static void Main() { получается вывод 1 Однако при переносе объявления x за пределы цикла: static D[] F() { вывод имеет вид 5 Если в цикле for объявляется переменная итерации, то сама эта переменная считается объявленной за пределами цикла. Таким образом, если изменить пример, чтобы захватывать саму переменную итерации static D[] F() { то будет захвачен только один экземпляр переменной итерации. В этом случае вывод имеет вид 3 Делегаты анонимных функций могут иметь некоторые общие захваченные переменные и в то же время иметь отдельные экземпляры других переменных. Например, если F изменить на static D[] F() { то три делегата будут захватывать один экземпляр x, но разные экземпляры y. Вывод будет иметь вид: 1 1 Отдельные анонимные функции могут захватывать один экземпляр внешней переменной. В данном примере: using System; delegate void Setter(int value); delegate int Getter(); class Test две анонимные функции захватывают один экземпляр локальной переменной x и поэтому они могут «взаимодействовать» через эту переменную. Вывод в данном примере имеет вид: 5 7.14.5 Вычисление выражений анонимных функций Анонимная функция F всегда должна преобразовываться в тип делегата D или тип дерева выражения E либо напрямую, либо с помощью выполнения выражения создания делегата new D(F). Это преобразование определяет результат анонимной функции, как описано в разделе §6.5. 7.15 Выражения запросов; Выражения запросов представляют собой подмножество синтаксических конструкций языка для запросов, похожих запросы иерархических или реляционных языков запросов, таких как SQL и XQuery. выражение запроса: предложение from: тело запроса: предложения тела запроса: предложение тела запроса: предложение let: предложение where: предложение join: предложение join into: предложение orderby: упорядочения: упорядочение: направление упорядочения: предложение select или group: предложение select: предложение group: продолжение запроса: Выражение запроса начинается с предложения from и заканчивается предложением select или group. После исходного предложения from могут идти предложения from, let, where, join или orderby. Каждое предложение from является генератором, предлагающим переменную диапазона, которая включает элементы последовательности. Каждое предложение let вводит переменную диапазона, которая представляет значение, вычисляемое с помощью предыдущих переменных диапазона. Каждое предложение where является фильтром для исключения элементов из результата. Каждое предложение join сравнивает указанные ключи исходной последовательности с ключами другой последовательности, выдавая совпадающие пары. Каждое предложение orderby изменят порядок элементов в соответствии с указанными критериями. Конечное предложение select или group задает формат результата в виде переменных диапазона. И наконец, предложение into можно использовать для «склеивания» запросов, рассматривая результаты одного запроса в качестве генератора для последующего запроса. 7.15.1 Неоднозначность в выражениях запросов Выражения запросов содержат определенное число «контекстных ключевых слов», то есть идентификаторов, у которых есть особое значение в конкретном контексте. В частности, это from, where, join, on, equals, into, let, orderby, ascending, descending, select, group и by. Чтобы не допустить появления неоднозначности в выражениях запросов, вызванной смешанным использованием этих идентификаторов в виде ключевых слов и простых имен, при появлении в любом месте выражения запроса такие идентификаторы считаются ключевыми словами. В этом смысле выражением запроса является любое выражение, которое начинается со строки «from идентификатор», за которым следует любая лексема кроме «;», « = » или «,». Чтобы использовать эти слова в качестве идентификаторов в выражении запроса, перед ними можно указать « @ » (§2.4.2). 7.15.2 Перевод выражений запросов В языке C# не задается семантика выполнения выражений запросов. Вместо этого выражения запросов переводятся в вызовы методов, которые соответствуют шаблону выражения запроса (§7.15.3). В частности, выражения запросов переводятся в вызовы методов с именами Where, Select, SelectMany, Join, GroupJoin, OrderBy, OrderByDescending, ThenBy, ThenByDescending, GroupBy и Cast. Эти методы должны иметь специальные подписи и типы результатов, как описано в разделе §7.15.3. Эти методы могут быть методами экземпляра запрашиваемого объекта или методами расширения, внешними для объекта, и в них может реализовываться фактическое выполнение запроса.
|