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

4.3.2Преобразования распаковки

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

  • Из типа object к любому типу_значений.

  • Из типа System.ValueType к любому типу_значений.

  • Из любого типа_интерфейса к любому необнуляемому_типу_значений, реализующему тип_интерфейса.

  • Из любого типа_интерфейса к любому обнуляемому_типу, базовый тип которого реализует тип_интерфейса.

  • Из типа System.Enum к любому перечисляемому_типу.

  • Из типа System.Enum к любому обнуляемому_типу, базовым для которого является перечисляемый_тип.

Обратите внимание, что если явное преобразование из параметра типа во время выполнения включает в себя преобразование из ссылочного типа к типу значений, оно будет выполнено как преобразование распаковки (§6.2.6).

При выполнении операции распаковки для необнуляемого_типа_значений сначала проверяется, является ли экземпляр объекта упакованным значением указанного необнуляемого_типа_значений. После этого выполняется копирование значения из экземпляра.

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

Если рассматривать предполагаемый класс упаковки, описанный в предыдущем разделе, преобразование распаковки объекта box к типу_значений T будет включать в себя выполнение выражения ((Box<T>)box).value. Таким образом, операторы

object box = 123; int i = (int)box;

будут соответствовать операторам

object box = new Box<int>(123); int i = ((Box<int>)box).value;

Для успешного выполнения преобразования распаковки в указанный необнуляемый_тип_значений значение исходного операнда должно содержать ссылку на упакованное значение этого необнуляемого_типа_значений. Если исходный операнд имеет значение null, порождается исключение System.NullReferenceException. Если исходный операнд содержит ссылку на несовместимый объект, порождается исключение System.InvalidCastException.

Для успешного выполнения операции распаковки в заданный обнуляемый_тип исходный операнд должен иметь значение null или содержать ссылку на упакованное значение необнуляемого_типа_значений, являющегося базовым для обнуляемого_типа. Если исходный операнд содержит ссылку на несовместимый объект, порождается исключение System.InvalidCastException.

4.4Сформированные типы

Объявление универсального типа определяет несвязанный универсальный тип, который используется в качестве шаблона для формирования различных типов посредством применения аргументов типа. Аргументы типа записываются с помощью угловых скобок («<» и «>») непосредственно после имени универсального типа. Тип, содержащий как минимум один аргумент типа, называется сформированным типом. Сформированный тип может использоваться в большинстве конструкций языка, в которых используется имя типа. Несвязанный универсальный тип может использоваться только в выражении_typeof (§7.6.11).

Сформированные типы также могут использоваться в выражениях в качестве простых имен (§7.6.2) или при доступе к членам (§7.6.4).

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

namespace Widgets { class Queue {...} class Queue<TElement> {...} }

namespace MyApplication { using Widgets;

class X { Queue q1; // Non-generic Widgets.Queue Queue<int> q2; // Generic Widgets.Queue } }

Имя_типа должно определять сформированный тип, даже если в нем прямо не заданы параметры типа. Это может произойти, если тип является вложенным в объявлении универсального класса, а тип экземпляра в содержащем объявлении неявно используется для поиска имен (§10.3.8.6):

class Outer<T> { public class Inner {...}

public Inner i; // Type of i is Outer<T>.Inner }

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

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