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

7.3.6Числовое расширение

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

В качестве примера числового расширения можно рассмотреть стандартные реализации бинарного оператора *:

int operator *(int x, int y); uint operator *(uint x, uint y); long operator *(long x, long y); ulong operator *(ulong x, ulong y); float operator *(float x, float y); double operator *(double x, double y); decimal operator *(decimal x, decimal y);

При применении правил разрешения перегрузки (§7.5.3) к этому набору операторов результатом является первый оператор, для которого существуют неявные преобразования операндов. Например, для операции b * s, где b имеет тип byte, а s — тип short, при разрешении перегрузки будет выбрано operator *(int, int). Таким образом, b и s преобразуются в тип int, и результат имеет тип int. Точно так же для операции i * d, где i имеет тип int, а d — тип double, при разрешении перегрузки будет выбрано operator *(double, double).

7.3.6.1Числовое расширение унарных операторов

Числовое расширение унарных операторов выполняется для операндов стандартных унарных операторов +, – и ~. Числовое расширение унарных операторов заключается в простом преобразовании операндов типа sbyte, byte, short, ushort или char в тип int. Кроме того, для унарного оператора – при числовом расширении унарного оператора происходит преобразование операндов с типом uint в тип long.

7.3.6.2Числовое расширение бинарных операторов

Числовое расширение бинарных операторов выполняется для операндов стандартных бинарных операторов +, –, *, /, %, &, |, ^, ==, !=, >, <, >= и <=. При числовом расширении бинарных операторов оба операнда преобразуются в общий тип. Для операторов, отличных от операторов отношения, этот тип становится типом результата операции. Числовое расширение бинарных операторов состоит в применении следующих правил в указанном здесь порядке.

  • Если один из операндов имеет тип decimal, то другой операнд преобразуется в тип decimal, либо если другой операнд имеет тип float или double, то возникает ошибка времени привязки.

  • Иначе, если один из операндов имеет тип double, то другой операнд преобразуется в тип double.

  • Иначе, если один из операндов имеет тип float, то другой операнд преобразуется в тип float.

  • Иначе, если один из операндов имеет тип ulong, то другой операнд преобразуется в тип ulong, либо если другой операнд имеет тип sbyte, short, int или long, то возникает ошибка времени привязки.

  • Иначе, если один из операндов имеет тип long, то другой операнд преобразуется в тип long.

  • Иначе, если один из операндов имеет тип uint, а другой операнд имеет тип sbyte, short или int, то оба операнда преобразуются в тип long.

  • Иначе, если один из операндов имеет тип uint, то другой операнд преобразуется в тип uint.

  • Иначе оба операнда преобразуются в тип int.

Обратите внимание, что первое правило запрещает любые операции, в которых смешиваются тип decimal и типы double или float. Это правило вытекает из того факта, что неявное преобразование между типом decimal и типом double или float не существует.

Также обратите внимание, что операнд не может иметь тип ulong, когда другой операнд имеет целый тип со знаком. Это так, поскольку не существует целого типа, который может представлять полный спектр значений ulong вместе с целыми типами со знаком.

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

В этом примере

decimal AddPercent(decimal x, double percent) { return x * (1.0 + percent / 100.0); }

возникает ошибка времени привязки, поскольку значения типа decimal нельзя умножать на значение типа double. Эта ошибка устраняется с помощью явного преобразования второго операнда в тип decimal, ср.:

decimal AddPercent(decimal x, double percent) { return x * (decimal)(1.0 + percent / 100.0); }

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