Skip to content

tags: - operators - precedence - reference


Operator Precedence

This document provides a comprehensive reference for operator precedence and associativity in EverSharp.

Precedence Table

Operators are listed from highest (1) to lowest (11) precedence. Operators with the same precedence level are evaluated according to their associativity.

| Level | Operators | Description | Associativity | Example | | ----- | ---------------------------- | ---------------------------------- | ------------- | ---------------------------- | ---- | ---------- | | 1 | () [] . | Grouping, subscript, member access | Left | func() arr[0] obj.prop | | 2 | ++ -- | Postfix increment/decrement | Left | count++ index-- | | 3 | ! - | Logical NOT, unary minus | Right | !flag -value | | 4 | * / % | Multiplication, division, modulo | Left | a * b x / y n % 10 | | 5 | + - | Addition, subtraction | Left | a + b x - y | | 6 | < <= > >= | Relational operators | Left | a < b x >= y | | 7 | == != | Equality operators | Left | a == b x != y | | 8 | && | Logical AND | Left | a && b | | 9 | | | | Logical OR | Left | a \|\| b | | 10 | ? : | Ternary conditional | Right | cond ? a : b | | 11 | = += -= *= /= %= | Assignment operators | Right | x = 5 x += 2 |

Associativity Explained

Left Associativity

Left-associative operators group from left to right:

// Addition (left-associative)
a +
  b +
  c(
    // Evaluated as:
    a + b
  ) +
  c;

// Subtraction (left-associative)
10 -
  5 -
  2(
    // Evaluated as:
    10 - 5
  ) -
  2; // Result: 3

// Multiplication (left-associative)
2 *
  3 *
  4(
    // Evaluated as:
    2 * 3
  ) *
  4; // Result: 24

// Division (left-associative)
100 /
  5 /
  2(
    // Evaluated as:
    100 / 5
  ) /
  2; // Result: 10

Right Associativity

Right-associative operators group from right to left:

// Assignment (right-associative)
a = b = c;
// Evaluated as:
a = b = c;

// Example:
x = y = 5;
// First: y = 5 (y becomes 5)
// Then: x = (result of y = 5) which is 5
// Result: both x and y are 5

// Ternary operator (right-associative)
a ? b : c ? d : e;
// Evaluated as:
a ? b : c ? d : e;

Precedence Examples

Example 1: Arithmetic Operations

result = 2 + 3 * 4;
// Multiplication has higher precedence than addition
// Evaluated as: 2 + (3 * 4) = 2 + 12 = 14

result = 10 - 5 + 3;
// Same precedence, left-to-right
// Evaluated as: (10 - 5) + 3 = 5 + 3 = 8

result = (20 / 4) * 2;
// Same precedence, left-to-right
// Evaluated as: (20 / 4) * 2 = 5 * 2 = 10

Example 2: Comparison and Logical

result = 5 < 10 && 3 > 1;
// Comparison operators evaluated first, then logical AND
// Evaluated as: (5 < 10) && (3 > 1) = true && true = true

result = (x > 5 && y < 10) || z == 0;
// AND has higher precedence than OR
// Evaluated as: ((x > 5) && (y < 10)) || (z == 0)

result = !flag && value > 0;
// Unary NOT has higher precedence than AND
// Evaluated as: (!flag) && (value > 0)

Example 3: Mixed Operations

result = 10 + 5 * 2 < 30 && true;
// Precedence: *, +, <, &&
// Step 1: 5 * 2 = 10
// Step 2: 10 + 10 = 20
// Step 3: 20 < 30 = true
// Step 4: true && true = true

result = a = b + c * d;
// Precedence: *, +, =
// Step 1: c * d
// Step 2: b + (result of step 1)
// Step 3: a = (result of step 2)

Example 4: Unary Operators

result = -5 + 3;
// Unary minus has higher precedence than addition
// Evaluated as: (-5) + 3 = -2

result = !false || true;
// Evaluated as: (!false) || true = true || true = true

result = -x * y;
// Evaluated as: (-x) * y

result = !(a > b);
// Evaluated as: !(a > b)  // Parentheses force evaluation order

Example 5: Member Access and Calls

result = arr[0].ToUpper();
// Left-to-right evaluation:
// Step 1: arr[0] (subscript)
// Step 2: (result).ToUpper() (member access and call)

result = obj.method(a + b);
// Step 1: a + b (function argument evaluated first)
// Step 2: obj.method((result))

result = items.Filter((x) => x > 5).Length;
// Left-to-right:
// Step 1: items.Filter((x) => x > 5)
// Step 2: (result).Length

Common Mistakes and Solutions

Mistake 1: Comparison Chains

// WRONG: Doesn't work as expected
if (10 < x < 20) {
  // Syntax error or unexpected behavior
  // ...
}

// CORRECT: Use logical AND
if (x > 10 && x < 20) {
  // ...
}

Mistake 2: Division and Multiplication

// Be careful with order
result = (10 / 2) * 5;
// Evaluated as: (10 / 2) * 5 = 5 * 5 = 25
// NOT: 10 / (2 * 5) = 10 / 10 = 1

// Use parentheses for clarity
result = 10 / (2 * 5); // Result: 1

Mistake 3: Logical Operators

// WRONG: Bitwise AND doesn't exist
result = flag1 & flag2; // Error

// CORRECT: Use logical AND
result = flag1 && flag2;

Mistake 4: Assignment in Conditions

// WRONG: Assignment instead of comparison
if ((x = 5)) {
  // Assigns 5 to x, always true
  // ...
}

// CORRECT: Use comparison
if (x == 5) {
  // ...
}

Mistake 5: Unary Minus with Variables

// Can be confusing without spaces
result = x - y; // Could be x - y or x-y (separate identifier)

// BETTER: Use spaces for clarity
result = x - y;
result = -y;

Precedence Disambiguation

Using Parentheses

When in doubt, use parentheses to make intent clear:

// Unclear intent:
result = a + b * c > d && e;

// Clear intent with parentheses:
result = a + b * c > d && e;

// Or:
result = a + b * c > d && e; // Minimal parentheses

Readability vs. Brevity

// Technically correct but hard to read:
x = y = z = (a + (b * c) / d > e && f) || g;

// More readable with parentheses:
temp1 = (b * c) / d;
temp2 = a + temp1;
temp3 = temp2 > e;
result = (temp3 && f) || g;
x = y = z = result;

// Or with strategic parentheses:
x = y = z = (a + (b * c) / d > e && f) || g;

Operator Details

Arithmetic Operators

// Higher precedence: * / %
result = 10 + 5 * 2; // 20 (not 30)
result = 10 - 6 / 2; // 7 (not 2)
result = (17 % 5) + 3; // 5 (2 + 3)

// Same precedence: + -
result = 10 + 5 - 3; // 12 ((10 + 5) - 3)
result = 10 - 5 + 3; // 8 ((10 - 5) + 3)

// Same precedence: * / %
result = (20 / 4) * 2; // 10 ((20 / 4) * 2)
result = (20 % 6) / 2; // 1 ((20 % 6) / 2 = 2 / 2)

Comparison Operators

// All comparison operators have same precedence
result = 5 < 10 > 3; // Error: can't chain comparisons

// Must use logical operators:
result = 5 < 10 && 10 > 3; // true

Logical Operators

// AND has higher precedence than OR
result = true || (false && false);
// Evaluated as: true || (false && false) = true || false = true

result = (false && true) || true;
// Evaluated as: (false && true) || true = false || true = true

// Use parentheses to change precedence:
result = (true || false) && false; // false

Assignment Operators

// Right-associative
a = b = c = 5;
// Evaluated as: a = (b = (c = 5))
// Result: all three are 5

// Compound assignment
x = 10;
x += 5; // Equivalent to: x = x + 5

// Compound assignment with expressions
x = 10;
x += 2 * 3; // x = x + (2 * 3) = 10 + 6 = 16

Ternary Operator

// Right-associative
result = a ? b : c ? d : e;
// Evaluated as: a ? b : (c ? d : e)

// Example:
x = 5;
result = x < 0 ? "negative" : x == 0 ? "zero" : "positive";
// Since x = 5:
// Step 1: x < 0 ? "negative" : (...)  // false, so evaluate else part
// Step 2: x == 0 ? "zero" : "positive"  // false, so result = "positive"

Postfix Operators

// Postfix operators evaluate before other operations
result = count++ + 5;
// Step 1: Use current value of count (e.g., 10)
// Step 2: Add 5: 10 + 5 = 15
// Step 3: Increment count to 11
// Result: 15, count is now 11

// Multiple postfix operators
x = arr[index++];
// Step 1: Get current index value
// Step 2: Access arr[current index]
// Step 3: Increment index

Best Practices

1. Use Parentheses for Clarity

// Less clear:
total = baseAmount + baseAmount * taxRate;

// More clear:
total = baseAmount + baseAmount * taxRate;

// Even clearer:
tax = baseAmount * taxRate;
total = baseAmount + tax;

2. Break Complex Expressions

// Hard to read:
result = (((a + b) * (c - d)) / (e + f) > threshold && isValid) || override;

// Easier to read:
sum = a + b;
diff = c - d;
quotient = (sum * diff) / (e + f);
meetsThreshold = quotient > threshold;
result = (meetsThreshold && isValid) || override;

3. Consistent Style

// Good: Spaces around operators
result = a + b * c;

// Avoid: Inconsistent spacing
result = a + b * c;

4. Explicit Comparisons

// WRONG: EverSharp doesn't support truthiness
if (count) {
} // Error

// CORRECT: Explicit comparison
if (count > 0) {
}
if (flag == true) {
}
if (value != null) {
}

Quick Reference

By Category

Highest Precedence (evaluate first):

  1. Member access: . [] ()
  2. Postfix: ++ --
  3. Unary: ! -

Arithmetic: 4. Multiply/Divide: * / % 5. Add/Subtract: + -

Comparison: 6. Relational: < <= > >= 7. Equality: == !=

Logical: 8. AND: && 9. OR: ||

Conditional and Assignment: 10. Ternary: ? : 11. Assignment: = += -= *= /= %=

Mnemonic

"Please Excuse My Dear Aunt Sally Calls Eagerly And Often Takes All"

  • Please: Parentheses/Primary
  • Excuse: Exponents (N/A in EverSharp)
  • My: Multiply/Divide/Modulo
  • Dear: (covered in My)
  • Aunt: Add/Subtract
  • Sally: (Add/Subtract)
  • Calls: Comparison
  • Eagerly: Equality
  • And: Logical AND
  • Often: Logical OR
  • Takes: Ternary
  • All: Assignment

See Also