Выбрать главу

{

    //перегрузка операций

    byte b1=1, b2 =2, Ь3;

    short sh1;

    int ini;

    //b3 = b1 + Ь2; //ошибка: результат типа int

    b3 = (byte) (b1+Ь2);

    //sh1 = b1 + Ь2; //ошибка: результат типа int

    sh1 = (short)(b1+b2);

    in1 = b1+ b2 + sh1;

    Console.WriteLine("Ь3= " + Ь3 + " sh1= "+ sh1 +" in1= " + in1);

}//Express

Разберем этот фрагмент. Начнем с первого закомментированного оператора присваивания b3=b1+Ь2;. Выражение здесь простейшее, включает одну бинарную операцию сложения. Оба операнда имеют тип byte, казалось бы, и результат должен быть типа byte и без помех присвоен переменной b3. Однако это не так. Для данных типа byte нет перегруженной реализации сложения. Ближайшей операцией является сложение целых типа int. Поэтому оба операнда преобразуются к типу int, выполняется операция сложения, результат имеет тип int и не может быть неявно преобразован в тип byte, — возникает ошибка еще на этапе компиляции. Корректная запись показана в следующем операторе. Аналогичная ситуация возникает, когда в левой части оператора стоит переменная типа short, — и здесь необходимо явное приведение к типу. Этого приведения не требуется, когда в левой части стоит переменная типа int.

Давайте разберем, как в данном примере организован вывод в методе WriteLine. До сих пор при вызове метода задавалось несколько параметров и использовалась форма вывода данных с подстановкой значений параметров в строку, заданную первым параметром. Здесь же есть только один параметр — это строка, заданная сложным выражением. Операция, многократно применяемая в этом выражении, это сложение " +". Операнды сложения имеют разный тип: левый операнд имеет тип string, правый — арифметический (byte, short, int). в этом случае арифметический тип преобразуется к типу string и выполняется сложение строк (конкатенация). Напомню, при преобразовании арифметического типа к типу string вызывается метод Tostring(), определенный для всех встроенных типов. Результатом этого выражения является строка, она и будет результатом вывода метода WriteLine.

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

С чего начинается выполнение выражения

Вычисление выражения начинается с выполнения операций высшего приоритета. Первым делом вычисляются выражения в круглых скобках — (ехрr), определяются значения полей объекта — х. у, вычисляются функции — f (х), переменные с индексами — а [i]. Выполнение этих операций достаточно понятно и не нуждается в комментировании. Операции checked и unchecked включают и выключают проверку преобразований арифметического типа в выражениях, которым они предшествуют. О других операциях этой категории скажу чуть подробнее.

Операции "увеличить" и "уменьшить" (increment, decrement)

Операции "увеличить на единицу" и "уменьшить на единицу" могут быть префиксными и постфиксными. К высшему приоритету относятся постфиксные операции х++ и х-. Префиксные операции имеют на единицу меньший приоритет. Главной особенностью как префиксных, так и постфиксных операций является побочный эффект, в результате которого значение х увеличивается (++) или уменьшается (-) на единицу. Для префиксных (++х, — х) операций результатом их выполнения является измененное значение х, постфиксные операции возвращают в качестве результата значение х до изменения. Приведу пример применения этих операций, дополнив метод Express новым фрагментом:

//операции increment и decrement

//Следующее выражение допустимо, но писать подобное никогда не следует

in1 = ++in1 +in1+ in1++;

//in2 = ++in1 + in1++ + in1;

Console.WriteLine(" in1= " + in1);

Обратите внимание, что хотя у постфиксной операции высший приоритет, это вовсе не означает, что при вычислении выражения вначале выполнится операция in1++, затем ++in1, и только потом будет проводиться сложение. Нет, вычисления проводятся в том порядке, в котором они написаны. Поскольку на входе значение in1 было равно 6, то выражение будет вычисляться следующим образом: