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

7.17.2Сложное присваивание

Если левый операнд выражения составного присваивания имеет форму E.P или E[Ei], где E имеет динамический тип во время компиляции, то операция присваивания динамически привязывается (§7.2.2). В этом случае тип времени компиляции выражения присваивания динамический, а разрешение, приведенное ниже, будет иметь место во время выполнения на основе типа E времени выполнения.

Операция вида x op= y обрабатывается с применением разрешения перегрузки (§7.3.4), как если бы операция записывалась в виде x op y. Тогда

  • Если тип возвращаемого значения выбранного оператора может быть неявно преобразован в тип x, то операция вычисляется как x = x op y, за исключением того, что x вычисляется только один раз.

  • Если выбранный оператор является стандартным оператором, то если тип возвращаемого значения выбранного оператора может быть явно преобразован в тип x и если y может быть неявно преобразован в тип x или оператор является оператором сдвига, то операция вычисляется как x = (T)(x op y), где T имеет тип x, за исключением того, что x вычисляется только один раз.

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

Выражение «вычисляется только один раз» означает, что при вычислении x op y, результаты любого составляющего выражения в x временно сохраняются и затем используются повторно при присваивании для x. Например, в присваивании A()[B()] += C(), где A является методом, возвращающим значение int[], а B и C являются методами, возвращающими значение int, эти методы вызываются только один раз в последовательности A, B, C.

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

Второе правило (см. выше) позволяет в определенных контекстах вычислять x op= y как x = (T)(x op y). Существует правило, согласно которому стандартные операторы можно использовать в качестве сложных операторов, когда левый операнд имеет тип sbyte, byte, short, ushort или char. Даже если оба аргумента имеют один из этих типов, стандартные операторы дают результат типа int, как описано в разделе §7.3.6.2. Таким образом, без приведения типов присвоить результат левому операнду не удастся.

Интуитивным результатом применения правила для стандартных операторов является просто то, что операция x op= y допустима, если допустимы обе операции x op y и x = y. В примере

byte b = 0; char ch = '\0'; int i = 0;

b += 1; // Ok b += 1000; // Error, b = 1000 not permitted b += i; // Error, b = i not permitted b += (byte)i; // Ok

ch += 1; // Error, ch = 1 not permitted ch += (char)1; // Ok

интуитивной причиной для каждой ошибки является то, что соответствующее простое присваивание также вызвало бы ошибку.

Это также означает, что сложные операции присваивания поддерживают операции с нулификацией. В примере

int? i = 0; i += 1; // Ok

используется оператор с нулификацией +(int?,int?).

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