Поделиться через


Приведение типов и их преобразование (руководство по программированию на C#)

Так как C# статически типируется во время компиляции, после объявления переменной его нельзя объявить снова или назначить значение другого типа, если этот тип неявно преобразуется в тип переменной. Например, string невозможно неявно преобразовать в int. Таким образом, после объявления i как int, вы не можете присвоить ему строку "Привет", как показано в следующем коде:

int i;

// error CS0029: can't implicitly convert type 'string' to 'int'
i = "Hello";

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

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

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

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

  • Преобразования с вспомогательными классами: для преобразования между несовместимыми типами, такими как целые числа и объекты, или шестнадцатеричные строки и System.DateTime массивы байтов, можно использовать System.BitConverter класс, System.Convert класс и Parse методы встроенных числовых типов, например Int32.Parse. Дополнительные сведения см. в следующих статьях:

  • Преобразование массива байтов в int

  • Преобразование строки в число

  • Преобразование между шестнадцатеричными строками и числовыми типами

Неявные преобразования

Для встроенных числовых типов неявное преобразование может быть выполнено, когда значение, которое нужно сохранить, может поместиться в переменную без усечения или округления. Для целочисленных типов это ограничение означает, что диапазон исходного типа является правильным подмножеством диапазона для целевого типа. Например, переменная типа long (64-разрядное целое число) может хранить любое значение, которое может хранить целое число int (32-разрядное целое число). В следующем примере компилятор неявно преобразует значение num справа в тип long перед назначением bigNum.

// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;

Полный список всех неявных числовых преобразований см. в разделе "Неявные числовые преобразования" статьи "Встроенные числовые преобразования".

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

Derived d = new Derived();

// Always OK.
Base b = d;

Явные преобразования

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

double x = 1234.7;
int a;
// Cast double to int.
a = (int)x;
Console.WriteLine(a);
// Output: 1234

Полный список поддерживаемых явных числовых преобразований см. в разделе "Явные числовые преобразования" статьи "Встроенные числовые преобразования".

Для ссылочных типов требуется явное приведение, если необходимо преобразовать из базового типа в производный тип:

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

Исключения преобразования типов во время выполнения

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

Animal a = new Mammal();
Reptile r = (Reptile)a; // InvalidCastException at run time

Явное приведение аргумента a к Reptile приводит к опасному предположению. Лучше не делать предположений, а проверять тип. C# предоставляет оператор is, чтобы проверить совместимость перед выполнением приведения. Дополнительные сведения см. в разделе «Безопасное приведение» с использованием сопоставления шаблонов и операторов as и is.

Спецификация языка C#

Дополнительные сведения см. в разделе "Преобразования " спецификации языка C#.

См. также