Урок 12. Перегрузка оператора преобразования C#
Двенадцатый урок учебника по объектно-ориентированному программированию на C# завершает исследование перегрузки операторов в C#. В этом материале описывается процесс перегрузки операторов преобразования, чтобы разрешить неявное и явное приведение между типами данных.
Операторы преобразования
Приведение типов позволяет преобразовать значение одного типа в другой тип данных, чтобы его можно было использовать в вычислениях или методах или в любой другой ситуации, когда текущий тип данных значения не подходит.
Преобразование типов данных, предоставляемых преобразованием, может быть неявным или явным. Неявное приведение происходит автоматически, когда был определен оператор неявного преобразования и оба типа данных совместимы. Явное приведение используется, когда два типа данных не полностью совместимы и требует, чтобы исходный тип был префиксом с оператором приведения. Этот оператор является желаемым типом данных, заключенным в скобки ().
В следующем примере кода показано сравнение преобразования с использованием неявных и явных приведений для базовых числовых типов данных. Обратите внимание на требование для оператора приведения для второго преобразования.
uint integer = 100; long longInteger; longInteger = integer; // Неявное приведение integer = (uint)longInteger; // Явное приведениеКогда вы создаете новый класс, он не обладает возможностями для приведения к другим типам данных. Каждое возможное приведение должно быть определено в классе и объявлено как неявное или явное. Как видно из вышеприведенного примера кода, неявное приведение может быть проще для чтения и может обеспечить более точный код. Однако для читателя не сразу очевидно, что происходит преобразование, и поэтому неявное приведение может скрыть проблемы, которые были бы более очевидными, если бы использовался явный оператор преобразования.
Как правило, неявное приведение следует использовать только в том случае, если нет риска потери данных или исключения. Явное приведение должно использоваться во всех других ситуациях. Это продемонстрировано в приведенном выше коде. Неявное приведение от меньшего целого к большему целому безопасно без риска, поскольку все возможные значения могут быть преобразованы. При преобразовании большого целого числа со знаком в меньшее целое число без знака существует риск того, что значение потеряет свой знак или будет слишком большим для преобразования, поэтому более подходящим является явное приведение.
Существуют некоторые ограничения на перегрузку операторов преобразования. Ключевые ограничения:
- Вы не можете создавать операторы, которые преобразуют класс в тип данных объекта. Преобразование в объект предоставляется автоматически, чтобы разрешить упаковку и распаковку.
- Вы не можете создавать операторы, которые преобразуют класс в определенный интерфейс. Если требуется преобразование в интерфейс, класс должен реализовать интерфейс. Интерфейсы будут описаны позже в руководстве по объектно-ориентированному программированию на C#.
- Вы не можете создавать операторы, которые преобразуют из базового класса в класс, производный от этого базового класса. Наследование классов будет описано позже в этом уроке.
Создание оператора неявного преобразования
Неявные и явные операторы приведения являются унарными операторами и, как таковые, переопределяются с использованием синтаксиса, аналогичного другим базовым унарным операторам. Следующий синтаксис предназначен для оператора неявного преобразования:
public static implicit operator result-type(op-type operand)Тип результата - это тип данных для возвращаемого значения операции. Тип операции - это тип данных для операнда, который должен быть преобразован. Один из двух типов данных должен совпадать с классом, в котором выполняется объявление.
Добавление преобразования Double в класс Vector
Используя синтаксис, описанный выше, мы теперь добавим оператор неявного преобразования в класс Vector. Этот оператор преобразует вектор в число с плавающей запятой двойной точности, представляющее длину вектора. Расчет длины уже присутствует как свойство класса, поэтому мы будем использовать эту функциональность повторно. Чтобы добавить новый оператор преобразования, добавьте следующий код в класс Vector:
public static implicit operator double(Vector v) { return v.Length; }Вы можете протестировать новый оператор преобразования, изменив метод Main программы:
static void Main(string[] args) { Vector v = new Vector(5, 5); double d = v; Console.WriteLine(d); // 7.07106781186548 }Создание оператора явного преобразования
Синтаксис для создания оператора явного преобразования аналогичен синтаксису неявной версии. Изменено только неявное ключевое слово. Синтаксис поэтому:
public static explicit operator result-type(op-type operand)Мы будем использовать явную версию синтаксиса оператора преобразования, чтобы вектор мог быть приведен как значение с плавающей запятой одинарной точности, представляющее длину вектора. Выбор явного оператора обусловлен потерей точности числа, когда длина преобразуется из dounle во float.
Чтобы добавить новый оператор преобразования, добавьте следующий код в класс Vector:
public static explicit operator float(Vector v) { return (float)v.Length; }Новое преобразование может быть проверено с использованием обновленного метода Main ниже. Обратите внимание на потерю точности, возникающую при приведении длины вектора.
static void Main(string[] args) { Vector v = new Vector(5, 5); float f = (float)v; Console.WriteLine(f); // 7.071068 }Примечание. В этом примере требуется использование оператора (float), поскольку преобразование было определено как явное. Удаление этого оператора приведения вызывает ошибку компилятора.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.