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

4.4.1Аргументы типа

Каждый аргумент в списке аргументов типа представляет собой тип.

список_аргументов_типа: < аргументы_типа >

аргументы_типа: аргумент_типа аргументы_типа , аргумент_типа

аргумент_типа: тип

В небезопасном коде (§18) аргумент_типа не может являться типом указателя. Каждый аргумент типа должен удовлетворять любым ограничениям, накладываемым на соответствующий параметр типа (§10.1.5).

4.4.2Открытые и закрытые типы

Все типы можно подразделить на открытые и закрытые типы. Открытый тип — это тип, в котором используются параметры типа. В частности:

  • Параметр типа определяет открытый тип.

  • Массив имеет открытый тип только в том случае, если тип элементов массива является открытым.

  • Сформированный тип является открытым только в том случае, если один или несколько его аргументов типа имеют открытый тип. Вложенный сформированный тип является открытым только в том случае, если один или несколько аргументов типа для него или для содержащих его типов имеют открытый тип.

Все остальные типы являются закрытыми.

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

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

4.4.3Связанные и несвязанные типы

Термин несвязанный тип обозначает не являющийся универсальным тип или несвязанный универсальный тип. Термин связанный тип обозначает не являющийся универсальным тип или сформированный тип.

Несвязанный тип ссылается на сущность, описанную в объявлении типа. Несвязанный универсальный тип сам по себе не является типом и не может использоваться в качестве типа переменной, аргумента или возвращаемого значения, а также в качестве базового типа. Несвязанный универсальный тип может использоваться только в выражениях typeof (§7.6.11).

4.4.4Соблюдение ограничений

При каждом использовании сформированного типа или универсального метода выполняется проверка предоставленных аргументов типа на предмет соответствия ограничениям, накладываемым на параметры типа при объявлении универсального типа или метода (§10.1.5). Для каждого предложения where выполняется проверка аргумента типа A, соответствующего параметру именованного типа, следующим образом:

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

  • Преобразование идентификации (§6.1.1).

  • Неявное преобразование ссылочного типа (§6.1.6)

  • Преобразование упаковки (§6.1.7), если тип A представляет собой необнуляемый тип значений.

  • Неявное преобразование ссылочного типа, упаковки или параметра типа из параметра типа A в C.

  • Если ограничение является ограничением ссылочного типа (class), тип A должен соответствовать одному из следующих ограничений:

  • Тип A является типом интерфейса, класса, делегата или массива. Обратите внимание, что типы System.ValueType и System.Enum являются ссылочными типами и соответствуют этому ограничению.

  • Тип A представляет собой параметр типа, являющегося ссылочным типом (§10.1.5).

  • Если ограничение является ограничением типа значений (struct), тип A должен соответствовать одному из следующих ограничений:

  • Тип A является типом структуры или перечисляемым типом и не является обнуляемым типом. Обратите внимание, что типы System.ValueType и System.Enum являются ссылочными типами и не соответствуют этому ограничению.

  • Тип A представляет собой параметр типа, для которого определено ограничение типа значений (§10.1.5).

  • Если ограничение является ограничением конструктора new(), тип A не может представлять класс abstract и должен включать не содержащий параметров открытый конструктор. Соответствие этому ограничению обеспечивается в том случае, если верно одно из следующих утверждений:

  • Тип A является типом значений, поскольку все типы значений содержат открытый конструктор по умолчанию (§4.1.2).

  • Тип A представляет собой параметр типа, для которого определено ограничение конструктора (§10.1.5).

  • Тип A представляет собой параметр типа, для которого определено ограничение типа значений (§10.1.5).

  • Тип A представляет собой класс, отличный от abstract, и содержит явно объявленный конструктор public, не имеющий параметров.

  • Тип A не представляет класс abstract и содержит конструктор по умолчанию (§10.11.4).

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

Поскольку наследование параметров типа не поддерживается, наследование ограничений также невозможно. В приведенном ниже примере требуется задать ограничение для параметра типа T типа D. При этом параметр T должен соответствовать ограничению, заданному в базовом классе B<T>. Напротив, для класса E не требуется задавать ограничение, поскольку List<T> реализует IEnumerable для любого T.

class B<T> where T: IEnumerable {...}

class D<T>: B<T> where T: IEnumerable {...}

class E<T>: B<List<T>> {...}

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