Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

4.5Параметры типа

Параметр типа представляет собой идентификатор, определяющий тип значений или ссылочный тип, с которым параметр связан во время выполнения.

параметр_типа: идентификатор

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

  • Не допускается прямое использование параметра типа для объявления базового класса (§10.2.4) или интерфейса (§13.1.3).

  • Правила поиска членов для параметров типа определяются применяемыми к ним ограничениями (при наличии таковых). Дополнительные сведения об ограничениях см. в разделе §7.4.

  • Доступные преобразования для параметров типа определяются применяемыми к ним ограничениями (при наличии таковых). Дополнительные сведения о преобразованиях см. в разделах §6.1.10 и §6.2.6.

  • Литерал null не может быть преобразован к типу, задаваемому параметром типа, за исключением случаев, когда параметр является ссылочным типом (§6.1.10). Вместо этого можно использовать выражение default (§7.6.13). Кроме того, если для параметра типа не предусмотрено ограничение типа значений, можно сравнить значение, которое имеет тип, задаваемый параметром типа, со значением null с помощью операторов «==» и «!=» (§7.10.6).

  • Выражение new (§7.6.10.1) может использоваться только с параметром типа, для которого предусмотрено ограничение_конструктора или ограничение типа значений (§10.1.5).

  • Параметр типа не может использоваться в атрибутах.

  • Параметр типа не может использоваться при доступе к члену (§7.6.4) или имени типа (§3.8) для определения статического члена или вложенного типа.

  • В небезопасном коде не допускается использование параметра типа в качестве неуправляемого_типа (§18.2).

Являясь типом, параметр типа представляет собой конструкцию, существующую исключительно во время компиляции. Во время выполнения каждый параметр типа связан с типом времени выполнения, заданным с помощью аргумента типа в объявлении универсального типа. Таким образом, переменная, объявленная с помощью параметра типа, во время выполнения будет иметь закрытый сформированный тип (§4.4.2). Во время выполнения для операторов и выражений, содержащих параметры типа, используются фактические типы, предоставленные в качестве аргументов типа для этих параметров.

4.6Типы дерева выражений

Дерево выражений обеспечивает представление анонимных функций в виде структур данных вместо исполняемого кода. Дерево выражений представляет собой значение типа дерева выражения вида System.Linq.Expressions.Expression<D>, где D — любой тип делегата. Далее в этой спецификации такие типы будут обозначаться с помощью сокращенной формы Expression<D>.

Если для анонимной функции существует преобразование к типу делегата D, для нее также существует и преобразование к типу дерева выражений Expression<D>. В результате преобразования анонимной функции к типу делегата создается делегат, содержащий ссылки на исполняемый код этой функции. При преобразовании анонимной функции к типу дерева выражений создается представление этой функции в виде дерева выражений.

Дерево выражений является эффективным представлением данных анонимной функции в памяти, обеспечивающим прозрачное и явное представление ее структуры.

Тип Expression<D> обладает типами параметров и возвращаемых значений, аналогичными типу делегата D.

В приведенном ниже примере анонимная функция представляется как в виде исполняемого кода, так и в виде дерева выражений. Поскольку существует преобразование к Func<int,int>, также существует и преобразование к Expression<Func<int,int>>:

Func<int,int> del = x => x + 1; // Code

Expression<Func<int,int>> exp = x => x + 1; // Data

В результате этих присвоений делегат del содержит ссылку на метод, который возвращает x + 1, а дерево выражений exp содержит ссылку на структуру данных, описывающую выражение x => x + 1.

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

Следует обратить внимание на следующие моменты:

  • Не все анонимные функции могут быть представлены в виде деревьев выражений. Например, не поддерживается представление анонимных функций, содержащих тела оператора и выражения присваивания. В этих случаях преобразование по-прежнему существует, однако вызывает ошибку во время компиляции.

  • Тип Expression<D> содержит метод экземпляра Compile, порождающий делегат типа D:

Func<int,int> del2 = exp.Compile();

При вызове этого делегата выполняется код, представленный деревом выражений. Таким образом, учитывая приведенные выше определения, del и del2 являются эквивалентными, то есть выполнение приведенных ниже операторов имеет одинаковый эффект:

int i1 = del(1);

int i2 = del2(1);

После выполнения этого кода переменным i1 и i2 присваивается значение 2.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]