2.3. Operators#

Operators in programming languages are symbols that tells the compiler or interpreter to perform specific operations. The operand combined with the operator makes an operation. In an operation, an operand is the data that is being operated on. The position of the operator, with respect to its operands, may be prefix, infix or postfix.

Common simple operators include

  • arithmetic (e.g. addition with +),

  • comparison (relational) (e.g. “greater than” with >),

  • logical (e.g. AND, also written && in some languages), and

  • assignment (e.g., =, +=) operators.

Additional types of operators include assignment (usually = or :=), field access in a record or object (usually .), and bitwise and shift operators.

Operators can be categorized based on the number of operands required. The three categories of operators based on the number of operands they require are:

  • Unary operators: which require one operand (e.g., ++, !)

  • Binary operators: which require two operands (e.g., +)

  • Ternary operators: which require three operands (e.g., condition ? consequent : alternative)

The table below summarizes key C# operators.

Category

Operators

Description

Example

Assignment

= += -= *= /= %= ++ --

Assign and update values

x = 5, x += 3

Arithmetic

+ - * / %

Mathematical operations

5 + 3, 14 / 4, 14 % 4

Comparison

== != > < >= <=

Compare values, return bool

5 > 3, x == y

Logical

&& || !

Combine or invert bool expressions

x > 0 && x < 10

Bitwise

& | ^ ~ << >>

Bit-level operations on integers

5 & 3, 5 << 1

2.3.1. C# Operator Types#

Every expression in C# is built from operands (values or variables) and operators (symbols that define the operation). Operators are grouped by what they do to their operands.

Note

C# vs Other Languages: Different language may have different operators doing the same thing.

Feature

C#

C / C++

Python

JavaScript

Logical AND / OR

&& ||

&& ||

and or

&& ||

Logical NOT

!

!

not

!

Integer division

/ (auto when both int)

/ (auto)

//

no built-in

Remainder

%

%

%

%

Exponentiation

Math.Pow(x, y)

pow(x,y)

**

**

Increment

++ --

++ --

no ++/--

++ --

String equality

== (value)

== (pointer!)

==

== (loose) / ===

Null coalescing

??

or idiom

??

In C# and JS, &&/\|\| use short-circuit evaluation: the right-hand side is only evaluated if needed. Python’s and/or do the same but return one of the operands rather than a strict bool. C/C++ lack a dedicated boolean type in older standards — 0 is false, anything else is true. [1]

2.3.1.1. Assignment Operators#

An assignment operator stores a value into a variable. The basic form is =, which should not be confused with == (equality test). C# also provides compound assignment operators that combine an arithmetic operation with assignment in one step, making code more concise:

int x = 10;   // assign
x += 3;       // x is now 13  (same as: x = x + 3)
x -= 2;       // x is now 11
x++;          // x is now 12  (post-increment)

2.3.1.2. Arithmetic Operators#

Arithmetic operators perform standard mathematical operations. An important subtlety in C# is integer division: when both operands are int, the / operator truncates toward zero and discards any remainder. To get a decimal result, at least one operand must be a double (or another floating-point type):

10 / 3;     // → 3  (integer division, remainder discarded)
10.0 / 3;   // → 3.333...  (double division)
10 % 3;     // → 1  (remainder)

2.3.1.3. Comparison Operators#

Comparison operators (also called relational operators) compare two values and always return a bool — either true or false. They are the primary building blocks of conditions in if statements and loops:

int a = 5, b = 3;
a == b;   // false — equality (note: two equals signs, not one)
a != b;   // true  — not equal
a > b;    // true  — greater than

A very common bug is writing = (assignment) instead of == (equality test) inside a condition. C# will often catch this as a compile-time error.

2.3.1.4. Logical Operators#

Logical operators combine bool expressions to build compound conditions. C# evaluates them using short-circuit rules: for &&, if the left side is false, the right side is skipped; for ||, if the left side is true, the right side is skipped. This matters when the right side has side-effects or could throw an exception.

Precedence: ! binds tightest, then &&, then ||. Use parentheses for clarity when mixing them:

bool x = true, y = false;
x && y;   // false — both must be true
x || y;   // true  — at least one must be true
!x;       // false — inverts x

2.3.1.5. Bitwise Operators#

Bitwise operators work on the individual bits of integer values. They are used in low-level programming, flags, masks, and performance-sensitive code. Each bit in the result is computed independently from the corresponding bits of the operands:

  5 in binary  →  0101
  3 in binary  →  0011
  5 & 3        →  0001  (AND: 1 only where both are 1)
  5 | 3        →  0111  (OR:  1 where either is 1)
  5 ^ 3        →  0110  (XOR: 1 where exactly one is 1)

Shift operators (<<, >>) move bits left or right, which is equivalent to multiplying or dividing by powers of 2:

5 << 1;   // → 10  (5 × 2)
5 >> 1;   // → 2   (5 ÷ 2, integer)

2.3.2. Operation Examples#

2.3.2.1. Assignment#

The = operator assigns a value. Compound operators (+=, -=, etc.) combine an operation with assignment. ++ and -- increment or decrement by 1:

x = 1;
x++       // post-increment operator; x++ increments the value of variable x after it's evaluated in an expression
x
x = 2;
++x       // pre-increment operator; ++x increments the value of variable x before it's evaluated in an expression
(2,4): error CS1002: ; expected

2.3.2.2. Arithmetic#

Basic arithmetic operations on numeric types:

int a = 10, b = 3;
a + b   // 13 — addition
a - b   // 7  — subtraction
a * b   // 30 — multiplication
a / b   // 3  — integer division (truncates toward zero)
a % b   // 1  — remainder
(2,6): error CS1002: ; expected

(3,6): error CS1002: ; expected

(4,6): error CS1002: ; expected

(5,6): error CS1002: ; expected

2.3.2.3. Division#

Division can be a little tricky in C#. For example:

5.0/2.0;
14.0/4.0;
(1,1): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement

(2,1): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement

But C# will implicitly turn the following expression to an int type:

14/4
3

Adding a decimal point would inform C# that you are using double instead of int:

14.0/4.0
14.0 / 4      // one of the operands is double type
6.0/3.0       // when the remainder is 0, the quotient is an int.
(1,9): error CS1002: ; expected

(2,9): error CS1002: ; expected

Note that C# stores values with only a limited precision, so the results of mathematical operations are only approximate in general. The following is an example that shows the double type has a precision of ~15-17 digits:

1.0/3
0.3333333333333333

2.3.2.4. Remainders#

Remainder is used to check if a number is divisible by another number. The remainder operator % computes the remainder after dividing its left-hand operand by its right-hand operand.

Try in the csharprepl:

14 % 7
14 % 4
int x = 0;
x = 7 % 5;  // x now contains 2
x = 9 % 5;  // x now contains 4
x = 5 % 5;  // x now contains 0
x = 4 % 5;  // x now contains 4
x = -4 % 5; // x now contains -4
x = 4 % -5; // x now contains 4
(1,7): error CS1002: ; expected

(2,7): error CS1002: ; expected

The precedence of % is the same as / and *, and hence higher than addition and subtraction, + and -.

2.3.2.5. Comparison#

Comparison operators return a bool (true or false):

int x = 1, y = 2;
x == y
x < y
x <= y
(2,7): error CS1002: ; expected

(3,6): error CS1003: Syntax error, ',' expected

(4,3): error CS1003: Syntax error, ',' expected

(4,6): error CS1003: Syntax error, ',' expected

(4,7): error CS1003: Syntax error, '>' expected

2.3.2.6. Logical#

Logical operators combine or invert bool expressions:

int x = 2;
x < 5 && x < 10
x < 5 || x < 10
!(x < 5 && x < 10)
(2,16): error CS1002: ; expected

2.3.2.7. Bitwise#

Bitwise operators work directly on the binary representation of integers:

int x = 5, y = 3;  // binary: x = 0101, y = 0011
x & y    // Bitwise AND:  0101 & 0011 = 0001 → 1
x | y    // Bitwise OR:   0101 | 0011 = 0111 → 7
x ^ y    // Bitwise XOR:  0101 ^ 0011 = 0110 → 6
~x       // Bitwise NOT:  ~0101 = ...11111010 → -6
x << 1   // Left shift:   0101 << 1 = 1010 → 10
x >> 1   // Right shift:  0101 >> 1 = 0010 → 2
(2,6): error CS1002: ; expected

(3,6): error CS1002: ; expected

(4,6): error CS1002: ; expected

(5,3): error CS1002: ; expected

(6,7): error CS1002: ; expected

2.3.3. Operator Precedence#

Earlier lines have higher precedence. Only operators used in this book are included:

obj.field  f(x)  a[i]  n++  n--  new
+  -  ! (Type)x  (Unary operators)
* / %
+ - (binary)
< > <= >=
== !=
&&
||
=  *=  /=  %=  +=  -=

All symbols are listed at the beginning of the index.

Parentheses for grouping are encouraged with less common combinations, even if not strictly necessary.

2.3.4. C# Operator Reference#

A more detailed overview of all the operators in C#:

No.

Type

Operator

Meaning

Example

Result

1

Assignment

=

Assign

x = 5

x is 5

+=

Add and assign

x += 3

x = x + 3

-=

Subtract and assign

x -= 3

x = x - 3

*=

Multiply and assign

x *= 3

x = x * 3

/=

Divide and assign

x /= 3

x = x / 3

%=

Remainder and assign

x %= 3

x = x % 3

++

Increment by 1

x++

x = x + 1

--

Decrement by 1

x--

x = x - 1

2

Arithmetic

+

Addition

5 + 3

8

-

Subtraction

5 - 3

2

*

Multiplication

5 * 3

15

/

Division

5.0 / 2.0

2.5

%

Remainder

14 % 4

2

3

Comparison

==

Equal to

x == y

true or false

!=

Not equal to

x != y

true or false

>

Greater than

5 > 3

true

<

Less than

5 < 3

false

>=

Greater than or equal to

5 >= 5

true

<=

Less than or equal to

5 <= 3

false

4

Logical

&&

AND — both must be true

x > 0 && x < 10

true or false

||

OR — at least one true

x < 0 || x > 10

true or false

!

NOT — inverts value

!(x > 10)

true or false

5

Bitwise

&

Bitwise AND

5 & 3

1

|

Bitwise OR

5 | 3

7

^

Bitwise XOR

5 ^ 3

6

~

Bitwise NOT (complement)

~5

-6

<<

Left shift

5 << 1

10

>>

Right shift

5 >> 1

2

6

Ternary

? :

Conditional — if/else shorthand

x > 0 ? "pos" : "neg"

"pos" or "neg"

7

Null Coalescing

??

Return left if not null, else right

name ?? "Unknown"

"Unknown" if name is null

??=

Assign only if null

name ??= "Unknown"

name set to "Unknown" if null

8

Type Testing

is

Check if object is a type

x is int

true or false

as

Cast to type, returns null if fails

obj as string

string or null

typeof

Get type information

typeof(int)

System.Int32

9

Member Access

.

Access member of object

obj.Name

value of Name

?.

Access member, null if object is null

obj?.Name

value or null

[]

Access element by index

arr[0]

first element

* For exponentiation, C# uses Math.Pow() where Python uses **.

Footnotes