Содержание
Выражение по сути является значением (выражает значение). Самый простой пример выражения — константа (например, 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 | нет |