То, что сужающие преобразования должны быть явными, а расширение преобразований может быть неявным, является лишь рекомендацией по проектированию. Можно создавать преобразования, которые нарушают это руководство, с помощью пользовательских преобразований. Также возможно использовать явное преобразование всякий раз, когда типы реализуют неявное преобразование.
- Расширяющее преобразование - это преобразование, в котором каждое значение исходного типа может быть представлено в типе результата.
- Сужающее преобразование - это преобразование, в котором некоторые значения исходного типа не могут быть представлены в типе результата.
Поскольку некоторые значения Int32
не могут быть представлены как Int16
, это сужающее преобразование. В зависимости от параметров компилятора значения вне диапазона Int16
либо переполняются, либо выдают исключение.
Вопреки тому, что я ранее сказал, эта концепция также применима к преобразованиям между базовыми и производными классами.
Вам нужно указывать типы как наборы возможных значений. И не о том, какие члены у них есть.
Каждый экземпляр производного класса всегда является допустимым значением переменной базового класса. Таким образом, приведение производного класса к базовому классу расширяется и, следовательно, неявно.
Некоторые экземпляры базового класса не являются допустимыми значениями производного класса (например, они являются производными от другого поддерева или являются экземплярами самого базового класса). Таким образом, приведение из базового класса к производному классу сужается и, таким образом, является явным.
Есть некоторые неявные преобразования, которые только расширяются в широком смысле, где преобразование с потерями.
В частности int
/ Int32
до float
/ Single
и long
/ Int64
до double
/ Double
. С этими преобразованиями некоторые входные значения могут быть представлены только приблизительно в типе результата.
Вам нужно рассматривать типы как набор допустимых значений. Затем вы видите, что каждый экземпляр производного класса также является допустимым значением для базового класса. Таким образом, преобразование из производного в базовый класс расширяется.
И наоборот, существуют значения базового класса, которые не являются допустимыми значениями производного класса.