Содержание
Выражение по сути является значением (выражает значение). Самый простой пример выражения — константа (например, 123) или переменная (например, x). Выражения можно объединять и изменять с помощью операторов. Операторы принимают один или более входящих операндов и возвращают новое выражение.
1 | 12 * 30 // * - оператор; 12 и 30 - операнды |
Операнды в свою очередь также могут быть выражениями (с оператором), таким образом можно создавать сложные составные (комплексные) выражения:
1 | 1 + (12 * 30) |
Операторы можно разделить на унарные, бинарные и тернарными в зависимости от количества операндов, которые принимает оператор (один, два или три). Бинарный оператор всегда располагается между двумя операндами (инфиксная запись).
Операторы встроенные в базовую часть языка называются основными (primary), например оператор вызова метода — ().
Выражения, которые не возвращают никакого значения, называются пустыми выражениями (void expression), например, Console.WriteLine (1). Пустые выражения не могут быть использованы в качестве операнда в других (комплексных) выражениях.
Выражения присваивания (Assignment Expressions)
В выражениях присваивания используется оператор = позволяющий присвоить переменной значение другого выражения.
1 | x = x * 5 |
Выражения присваивания не являются пустыми, они возвращают значение, присвоенное переменной. В силу этого выражения присваивания можно использовать в качестве операнда в других выражения.
1 | y = 5 * (x = 2) // y равен 10 |
Эта особенность может быть использована для инициализации нескольких переменных сразу:
1 | a = b = c = d = 0 |
Составные операторы присваивания (compound assignment operators) — сокращение, объединяющее присваивание с каким-либо другим оператором:
1 2 | x *= 2 // аналог x = x * 2 x <<= 1 // аналог x = x << 1 |
Приоритет и ассоциативность операторов
Когда выражение содержит несколько операторов, порядок их исполнения определяется в соответствии с приоритетом и ассоциативностью. Операторы с высоким приоритетом выполняются раньше операторов с низким, а если приоритет у операторов одинаковый, порядок их выполнения определяется ассоциативностью.
Бинарные операторы (за исключением оператора присваивания =, лямбды => и оператора объединения со значением Null ??) — лево-ассоциативные, т.е. выполняются слева направо (например, 8/4/2 выполняется как (8/4)/2). Порядок исполнения можно изменить с помощью скобок.
Оператор присваивания, лямбда, оператор объединения со значение Null и тернарный условный оператор — право-ассоциативные, т.е. исполняются справа налево.
Сводная таблица операторов C#
В следующей таблице операторы перечислены в порядке убывания их приоритета. Операторы расположенные под одним подзаголовком имеют одинаковый приоритет.
| Оператор | Название | пример | перегружаемость |
|---|---|---|---|
| Основные (Primary) | |||
| . | Доступ к членам | x.y | нет |
| -> | Указатель на структуру | x->y | нет |
| () | Вызов функции | x() | нет |
| [] | Массив/индекс | a[x] | через индексатор |
| ++ | Пост-инкремент | x++ | да |
| — | Пост-декремент | x— | да |
| new | Новый экземпляр | new Foo() | нет |
| stackalloc | Небезопасное выделение стека | stackalloc(10) | нет |
| typeof | Получить тип из идентификатора | typeof(int) | нет |
| checked | Включить проверку переполнения целочисленных типов | checked(x) | нет |
| unchecked | Выключить проверку переполнения целочисленных типов | unchecked(x) | нет |
| default | Значение по умолчанию | default(char) | нет |
| await | Ожидание | await mytask | нет |
| Унарные (Unary) | |||
| sizeof | Получить размер структуры (struct) | sizeof(int) | нет |
| + | Положительное значение | +x | да |
| — | Отрицательное значение | -x | да |
| ! | Отрицание (не) | !x | да |
| ~ | Поразрядное дополнение | ~x | да |
| ++ | Пре-инкремент | ++x | да |
| — | Пре-декремент | —x | да |
| () | Приведение к типу | (int)x | нет |
| * | Значение по адресу | *x | нет |
| & | Адрес значения | &x | нет |
| Мультипликативные (Multiplicative) | |||
| * | Умножение | x * y | да |
| / | Деление | x / y | да |
| % | Остаток от деления | x % y | да |
| Аддитивные (Additive) | |||
| + | Сложение | x + y | да |
| — | Вычитание | x — y | да |
| Операторы сдвига (Shift) | |||
| << | Сдвиг влево | x << 1 | да |
| >> | Сдвиг вправо | x >> 1 | да |
| ОПЕРАТОРЫ ОТНОШЕНИЙ (Relational) | |||
| < | Меньше чем | x < y | да |
| > | Больше чем | x > y | да |
| <= | Меньше или равно | x <= y | да |
| >= | Больше или равно | x >= y | да |
| is | Принадлежность экземпляра к типу | x is y | нет |
| as | Преобразование типа | x as y | нет |
| Операторы равенства (Equality) | |||
| == | Равно | x == y | да |
| != | Не равно | x != y | да |
| Логическое И (Logical And) | |||
| & | И | x & y | да |
| Логическое исключающее ИЛИ (Logical Xor) | |||
| ^ | Исключающее ИЛИ | x ^ y | да |
| Логическое ИЛИ (Logical Or) | |||
| | | ИЛИ | x | y | да |
| Условное И (Conditional And) | |||
| && | Условное И | x && y | через & |
| Условное ИЛИ (Conditional Or) | |||
| || | Условное ИЛИ | x || y | через | |
| Тернарный Условный оператор (Conditional (Ternary)) | |||
| ? : | Условие | isTrue ? then This : elseThis | нет |
| Присваивание и лямбда (Assignment and lambda) | |||
| = | Присвоить | x = y | нет |
| *= | Умножить себя на | x *= 2 | через * |
| /= | Разделить себя на | x /= 2 | через / |
| += | Прибавить к себе | x += 2 | через + |
| -= | Вычесть из себя | x -= 2 | через — |
| <<= | Сдвинуть себя влево на | x <<= 2 | через << |
| >>= | Сдвинуть себя вправо на | x >>= 2 | через >> |
| &= | Назначение И | x &= 2 | через & |
| ^= | Назначение исключающего ИЛИ | x ^= 2 | через ^ |
| |= | Назначение ИЛИ | x |= 2 | через | |
| => | Лямбда | x => x + 1 | нет |

