- •Тема 6. Основы программирования на языке c#
- •Условная операция
- •Операции checked и unchecked
- •Операция поглощения null
- •Безопасность типов
- •Преобразования типов
- •Неявные преобразования
- •Явные преобразования
- •Проверка равенства объектов
- •Упаковка и распаковка
- •Виртуальный метод Equals()
- •Статический метод Equals()
- •Проверка типов значений на равенство
- •Перегрузка операций
- •Как работают операции
- •Пример перегрузки операции: структура Vector
- •Добавление дополнительных перегрузок
- •Перегрузка операций сравнения
- •Пользовательские приведения
- •Реализация пользовательских приведений
- •Приведение между классами
- •Приведение между базовым и производным классами
- •Упаковывающие и распаковывающие приведения
- •Множественные приведения
Пользовательские приведения
Ранее в этой главе рассматривалось, как преобразовывать значения между предопределенными типами данных. Вы видели, что это делается посредством приведения. Также было показано, что C# позволяет выполнять приведения двух видов: явные и неявные. В этом разделе такие типы приведения рассматриваются более подробно.
При явном приведении вы явно обозначаете приведение в коде, указывая в скобках тип, к которому нужно привести:
int i = 3;
long l = I; // неявное
short s = (short)i; // явное
Для предопределенных типов данных явные приведения требуются тогда, когда возникает риск потери данных вследствие приведения. Ниже перечислено несколько примеров.
При преобразовании int в short, потому что размер short недостаточен для сохранения значения int.
При преобразовании типов данных со знаком в беззнаковые может быть получен неверный результат, если переменная со знаком содержит отрицательное значение.
При преобразовании типов с плавающей точкой в целые дробная часть теряется.
При преобразовании из типа, допускающего null-значения, в тип, не допускающий null, если исходная переменная содержит null, то генерируется исключение.
Дело в том, что, требуя явного приведения в коде, C# заставляет вас подтвердить, что вы понимаете степень риска потери данных, а потому при написании кода принимаете это во внимание.
Поскольку C# позволяет определять собственные типы данных (структуры и классы), это значит, что вам понадобятся средства поддержки приведения к этим типам и из них. Механизм заключается в том, что вы можете определить приведение как операцию-член одного из классов. Операция приведения должна быть помечена либо как implicit, либо как explicit, чтобы указать, каким образом ее предполагается использовать. Ожидается, что вы будете следовать тем же рекомендациям, что и в случае предопределенных приведений: если уверены, что данное приведение всегда безопасно независимо от значения исходной переменной, то определяете его как implicit (неявное). Однако когда извести но, что существует опасность, когда при определенных значениях что-то может пойти не так возможно, потеряются данные или сгенерируется исключение в таком случае приведение должно быть определено как explicit (явное).
Вы должны объявлять любое пользовательское приведение как явное, если могут существовать такие исходные значения, для которых оно завершится аварийно, либо есть риск возникновения исключений.
Синтаксис определения приведения подобен синтаксису перегруженных операций, который вы уже видели в настоящей главе. И это не случайно, потому что приведение рассматривается как операция, эффект применения которой состоит в преобразовании исходного типа в целевой. Чтобы проиллюстрировать синтаксис, рассмотрим фрагмент из примера структуры Currency, которая будет представлена ниже:
public static implicit operator float (Currency value)
{
// код обработки
}
Возвращаемый тип операции определяет целевой тип операции приведения, а единственный параметр исходный объект, подвергающийся преобразованию. Показанное здесь приведение позволяет неявно преобразовывать значение Currency в float. Обратите внимание, что если бы приведение было объявлено как explicit, то компилятор разрешал бы только явное его использование. Как и другие перегруженные операции, приведения должны быть объявлены как public и static.
Разработчики на C++ отметят, что в этом язык C# отличается от C++, где приведения являются членами экземпляров классов.
