C# - Operators Precedence
C# - Operator Precedence and Associativity
Section titled “C# - Operator Precedence and Associativity”In C#, operator precedence determines the order in which operations are performed in an expression with multiple operators. Think of it like the ‘order of operations’ (PEMDAS/BODMAS) from mathematics. Operators with higher precedence are evaluated before operators with lower precedence.
For example, in the expression var result = 10 + 5 * 2;, the multiplication operator * has higher precedence than the addition operator +. Therefore, 5 * 2 is calculated first (yielding 10), and then 10 + 10 is calculated. The final value assigned to result is 20, not 30.
When operators have the same precedence, their associativity determines the order of evaluation. Most operators are left-associative (evaluated from left to right), while a few, like assignment and null-coalescing operators, are right-associative (evaluated from right to left).
C# Operator Precedence Chart
Section titled “C# Operator Precedence Chart”The following table lists C# operators from highest to lowest precedence. Operators within the same category have the same precedence level.
| Precedence | Category | Operators | Associativity |
|---|---|---|---|
| 1 (Highest) | Primary | x.y, f(x), a[i], x?.y, x?[i], x++, x--, new, typeof, sizeof | Left-to-right |
| 2 | Unary | +, -, !, ~, ++x, --x, (T)x, ^ (index from end) | Right-to-left |
| 3 | Range | .. | Left-to-right |
| 4 | Multiplicative | *, /, % | Left-to-right |
| 5 | Additive | +, - | Left-to-right |
| 6 | Shift | <<, >>, >>> (unsigned right shift) | Left-to-right |
| 7 | Relational & Type-testing | <, >, <=, >=, is, as | Left-to-right |
| 8 | Equality | ==, != | Left-to-right |
| 9 | Bitwise AND | & | Left-to-right |
| 10 | Bitwise XOR | ^ | Left-to-right |
| 11 | Bitwise OR | | | Left-to-right |
| 12 | Logical AND | && | Left-to-right |
| 13 | Logical OR | || | Left-to-right |
| 14 | Null-coalescing | ?? | Right-to-left |
| 15 | Conditional (Ternary) | ?: | Right-to-left |
| 16 (Lowest) | Assignment & Lambda | =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=, ??=, => | Right-to-left |
Code Examples
Section titled “Code Examples”Example 1: Precedence (Multiplication vs. Addition)
Section titled “Example 1: Precedence (Multiplication vs. Addition)”The multiplication operator * is evaluated before the addition operator +.
// Modern C# with top-level statementsint result = 10 + 5 * 2; // Evaluates as 10 + (5 * 2)Console.WriteLine($"Result: {result}"); // Output: Result: 20Example 2: Using Parentheses to Override Precedence
Section titled “Example 2: Using Parentheses to Override Precedence”Parentheses () have the highest precedence and can be used to explicitly control the order of evaluation.
int result = (10 + 5) * 2; // Parentheses force addition to be evaluated firstConsole.WriteLine($"Result: {result}"); // Output: Result: 30Example 3: Associativity (Assignment)
Section titled “Example 3: Associativity (Assignment)”The assignment operator = is right-associative. The expression is evaluated from right to left.
int a, b, c;
// Right-to-left evaluation: c is assigned 10, then b is assigned the value of c, then a is assigned the value of b.a = b = c = 10;
Console.WriteLine($"a: {a}, b: {b}, c: {c}"); // Output: a: 10, b: 10, c: 10Best Practices & Common Pitfalls
Section titled “Best Practices & Common Pitfalls”When in Doubt, Use Parentheses
Section titled “When in Doubt, Use Parentheses”Even if you know the precedence rules, your colleagues might not. Using parentheses makes the code’s intent explicitly clear and reduces the cognitive load on the reader. This is a crucial practice for writing maintainable code in a team environment.
Good: var isValid = (user.IsLoggedIn && user.HasPermissions) || user.IsAdmin;
Less Clear: var isValid = user.IsLoggedIn && user.HasPermissions || user.IsAdmin;
Common Pitfall: & vs. &&
Section titled “Common Pitfall: & vs. &&”Be careful not to mix up the bitwise AND & with the logical AND &&. While both can be used in boolean expressions, && is “short-circuiting”—it won’t evaluate the right-hand side if the left-hand side is false. This is safer and more efficient. The bitwise & will always evaluate both sides.
string name = null;
// This will throw a NullReferenceException because `&` evaluates both sides.// bool isInvalid = name != null & name.Length > 0;
// This works correctly because `&&` short-circuits.// If name is null, the second part is never evaluated.bool isValid = name != null && name.Length > 0;Console.WriteLine($"Is valid: {isValid}"); // Output: Is valid: FalseFrequently Asked Questions (FAQ)
Section titled “Frequently Asked Questions (FAQ)”Q1: Which operators have the highest precedence in C#?
Primary operators like parentheses (), member access ., method invocation f(), and array indexing [] have the highest precedence.
Q2: What happens when two operators have the same precedence?
Associativity determines the order. For example, * and / have the same precedence and are left-associative, so 100 / 10 * 2 is evaluated as (100 / 10) * 2, which equals 20.
Q3: How can I avoid confusion with operator precedence?
The single best way to avoid ambiguity and bugs is to use parentheses () to explicitly group operations. This makes your code self-documenting and easier for everyone to understand.