Operators are fundamental building blocks in C#. They allow you to perform operations on variables and values. Whether you are assigning values, comparing data, performing arithmetic, evaluating conditions, or manipulating bits, operators are everywhere in C# programming.
Understanding operators in depth is essential because:
They define how expressions are computed
They influence program logic
They help build readable and efficient code
They are frequently used in interview questions
They form the core of decision-making, looping, calculations, and expressions
This article provides a complete, descriptive, and practical guide to all operators in C#, covering everything from basic arithmetic to advanced operator overloading.
What Are Operators in C#?
Operators are special symbols that tell the compiler what kind of operation to perform on operands (variables or values).
Example
int result = 5 + 3;
Here:
+ is the operator
5 and 3 are operands
result holds the output
C# provides a rich set of operators grouped into categories based on their purpose.
1. Arithmetic Operators
Arithmetic operators perform basic mathematical operations on numeric data.
These operators are used for computations such as addition, subtraction, multiplication, division, and modulus operations.
They are frequently used in programs involving calculations, loops, and data processing.
Division (/) behaves differently for integers (produces integer division) and floating-point values (produces decimal results).
The modulus operator (%) returns the remainder after division, which is often used in logical calculations such as even/odd checks.
| Operator | Description | Example |
|---|
| + | Addition | a + b |
| - | Subtraction | a - b |
| * | Multiplication | a * b |
| / | Division | a / b |
| % | Modulus (remainder) | a % b |
Example
int a = 10;
int b = 3;
Console.WriteLine(a + b); // 13
Console.WriteLine(a % b); // 1
2. Assignment Operators
Assignment operators assign values to variables.
The basic assignment operator (=) sets the value of the right-hand expression into the left-hand variable.
Compound assignment operators like +=, -=, *= simplify writing repetitive expressions (e.g., x = x + 5 becomes x += 5).
They improve code readability and reduce duplication, especially in loops or repeated operations.
These operators work with numbers, strings, and other types based on how the operator is overloaded.
| Operator | Description | Example |
|---|
| = | Assign value | a = 10 |
| += | Add and assign | a += 5 |
| -= | Subtract and assign | a -= 5 |
| *= | Multiply and assign | a *= 2 |
| /= | Divide and assign | a /= 2 |
| %= | Modulus and assign | a %= 2 |
Example
int x = 10;
x += 5; // x = x + 5
3. Comparison (Relational) Operators
Used to compare two values. They return true or false.
Relational operators are primarily used in decision-making, such as if, while, and for loops.
They compare values numerically or lexicographically, depending on the data type.
== and != compare equality, while >, <, >=, and <= evaluate relative ordering.
Comparing reference types usually checks memory references, not values (except for strings, which override comparison behavior).
| Operator | Meaning | Example |
|---|
| == | Equal to | a == b |
| != | Not equal to | a != b |
| > | Greater than | a > b |
| < | Less than | a < b |
| >= | Greater than or equal | a >= b |
| <= | Less than or equal | a <= b |
Example
int a = 5, b = 10;
Console.WriteLine(a < b); // true
4. Logical Operators
Used for combining Boolean expressions.
&& (AND) returns true only when both conditions are true. Useful for multi-step validations.
|| (OR) returns true if at least one condition is true, commonly used in optional-check logic.
! (NOT) negates a boolean value, flipping true ↔ false.
Logical operators use short-circuit evaluation, meaning unnecessary conditions are not evaluated, improving performance.
| Operator | Meaning | Example |
|---|
| && | Logical AND | cond1 && cond2 |
| ` | | ` |
| ! | Logical NOT | !cond |
Example
bool isLogin = true;
bool isAdmin = false;
Console.WriteLine(isLogin && isAdmin); // false
5. Unary Operators
Unary operators require only one operand.
Unary plus (+) and minus (-) express sign, although unary minus is more commonly used to negate values.
Increment (++) and decrement (--) operators modify values by 1 and exist in both prefix and postfix form.
Prefix modifies the value before use, while postfix modifies after use.
Logical NOT (!) is a unary operator that flips boolean expressions.
| Operator | Meaning | Example |
|---|
| + | Unary plus | +a |
| - | Unary minus | -a |
| ++ | Increment | a++ or ++a |
| -- | Decrement | a-- or --a |
| ! | Logical NOT | !flag |
Example
int a = 5;
Console.WriteLine(++a); // 6
6. Bitwise Operators
Used to manipulate bits at the low level.
Used in low-level programming, encryption algorithms, graphics, and performance-critical applications.
Bitwise AND, OR, XOR manipulate individual bits of numeric types.
Shift operators (<<, >>) move bits left or right, multiplying or dividing by powers of two.
They are extremely fast and efficient, but require a deeper understanding of binary representation.
| Operator | Meaning | Example |
|---|
| & | Bitwise AND | a & b |
| ` | ` | Bitwise OR |
| ^ | Bitwise XOR | a ^ b |
| ~ | Bitwise NOT | ~a |
| << | Left shift | a << 1 |
| >> | Right shift | a >> 1 |
Example
int a = 5; // 0101
int b = 3; // 0011
int c = a & b; // 0001 -> 1
7. Conditional (Ternary) Operator
Short form of if-else.
Evaluates a condition and returns one of two values depending on the result.
Improves code compactness and readability when simple conditions exist.
Useful for inline assignments, UI messages, and logging statements.
Should not be overused in complex conditions to avoid reduced readability.
condition ? value_if_true : value_if_false;
Example
int age = 20;
string message = age >= 18 ? "Adult" : "Minor";
8. Null-Coalescing Operators
Used when working with nullable values.
1. Null Coalescing: ??
Returns a fallback value if the left side is null.
Provides a fallback value if the left operand is null.
Prevents null reference exceptions in safe and clean code.
Frequently used when working with user input, configurations, or optional fields.
Helps avoid verbose null-checking logic.
string name = inputName ?? "Unknown";
2. Null Coalescing Assignment: ??=
Assigns a value only if the variable is null.
Assigns a value only if the variable is null.
Useful for initialising default values.
Improves code readability by reducing if(variable == null) checks.
Often used in constructors, methods, or caching logic.
name ??= "Guest";
9. Null-Conditional Operator ?.
Safely access a member without throwing null exceptions.
Allows safe access to members without throwing a null exception.
If the left operand is null, the entire expression evaluates to null.
Reduces verbose null-check patterns like if(x != null).
Commonly used when dealing with data from APIs, databases, or optional parameters.
string name = person?.FullName;
10. Type Check Operators
1. is Operator
Checks whether an object is of a certain type.
Checks if an object is of a specified type.
Can match patterns for additional validation.
Used in type-safe casting without risk of exception.
Helpful in polymorphism and pattern matching.
if (obj is string)
2. as Operator
Converts type safely; returns null if conversion fails.
Attempts safe casting; returns null instead of throwing exceptions.
Useful when you are unsure of the object's type.
Prevents runtime errors during invalid casts.
Works only with reference types.
string data = obj as string;
11. Type Conversion Operators
typeof
Returns the Type object.
Returns the System.Type object for a given type name.
Helpful in reflection, attributes, and dependency injection.
Allows inspecting metadata about classes.
Commonly used in logging and diagnostics.
Type t = typeof(string);
sizeof
Returns the size of value types.
Returns the size of value types in bytes.
Used primarily in unsafe code and performance-sensitive operations.
The size of types is fixed and determined by the runtime.
Helps in low-level memory manipulation.
int size = sizeof(int); // 4
12. Member Access Operator .
Used to access fields, methods, and properties.
Used to access members of a class or object (methods, fields, properties).
Enables chaining operations—for example, person.Address.City.
Foundation of object-oriented programming in C#.
Works with static and instance members.
person.Name
13. Indexer Operator []
Used for accessing elements in arrays and collections.
Used to access elements of arrays, lists, and dictionaries.
Enables random access to collection elements.
Index must be a valid integer or key (for dictionaries).
Supports slicing with C# range operator.
int value = arr[0];
14. Lambda Operator =>
Used in lambda expressions.
Used to define anonymous functions in a compact form.
Essential for functional programming and LINQ expressions.
Improves readability when defining small pieces of logic.
Often used in event handlers, delegates, and filtering operations.
(x, y) => x + y
15. Range Operator .. (C# 8+)
Used for slicing arrays.
Enables slicing arrays and sequences more cleanly.
Supports start and end boundaries.
Very useful in high-level data manipulation.
Works well with the Index and Range types introduced in modern C#.
var slice = arr[1..4];
16. Pattern Matching Operators (Modern C#)
Extend the power of the is and switch operators.
Allow matching values, types, conditions, and shapes.
Improve clarity and reduce boilerplate code.
Useful in modern object-oriented and functional styles of coding.
is Expression Patterns
if (item is int number)
switch Expression Patterns
var result = input switch
{
> 0 => "Positive",
< 0 => "Negative",
_ => "Zero"
};
17. Operator Overloading
C# allows custom operators in your classes.
Allows custom types to behave like built-in types using operators.
Useful in mathematical models, vectors, matrices, coordinates, etc.
Improves readability of domain-specific operations.
Should be used carefully to avoid confusing behavior.
Example
public static Point operator +(Point a, Point b)
{
return new Point(a.X + b.X, a.Y + b.Y);
}
Operator overloading is powerful in mathematical and domain-driven models.
18. Precedence and Associativity
C# follows strict rules for evaluating expressions.
Operator precedence defines the order in which operators are evaluated.
Multiplication, division, and modulus have higher precedence than addition and subtraction.
Parentheses override natural precedence to form clear expressions.
Understanding precedence is essential for writing correct expressions.
For example:
int result = 10 + 20 * 2; // Multiplication happens first
Always remember