Operators¶
EverSharp provides a comprehensive set of operators for arithmetic, comparison, logical operations, and more. This guide covers all operators with their precedence and usage patterns.
Operator Precedence¶
Operators are evaluated in the following order (highest to lowest precedence):
| Precedence | Operator | Description | Associativity |
| ----------- | ---------------------------- | ------------------------------------- | ------------- | ---------- | ------------- |
| 1 (highest) | () [] . | Grouping, array access, member access | Left-to-right |
| 2 | ++ -- | Postfix increment/decrement | N/A |
| 3 | ! - | Logical NOT, unary minus | Right-to-left |
| 4 | * / % | Multiplication, division, modulo | Left-to-right |
| 5 | + - | Addition, subtraction | Left-to-right |
| 6 | < > <= >= | Comparison | Left-to-right |
| 7 | == != | Equality | Left-to-right |
| 8 | && | Logical AND | Left-to-right |
| 9 | | | | Logical OR | Left-to-right |
| 10 | ?: | Ternary conditional | Right-to-left |
| 11 (lowest) | = += -= *= /= %= | Assignment | Right-to-left |
Arithmetic Operators¶
Addition +¶
// Numeric addition
sum = 10 + 20; // 30
total = price + tax; // Adds two numbers
// String concatenation
greeting = "Hello, " + "World"; // "Hello, World"
message = "Age: " + 30; // "Age: 30" (number converts to string)
Special behavior: If either operand is a string, performs concatenation.
Subtraction -¶
Multiplication *¶
Division /¶
quotient = 100 / 4; // 25
half = value / 2;
rate = premium / coverage; // 0.01 if premium=1000, coverage=100000
// Division by zero
// result = 10 / 0; // RuntimeException
Modulo %¶
Returns the remainder of division:
Use cases:
- Check even/odd:
x % 2 == 0 - Cycle through values:
index % arrayLength - Extract digits:
number % 10
Unary Minus -¶
Negates a number:
Comparison Operators¶
All comparison operators return boolean values.
Less Than <¶
10 < 20; // true
age < minAge; // true if age is less than minAge
"apple" < "banana"; // true (lexicographic)
Greater Than >¶
20 > 10; // true
premium > maxPremium; // true if premium exceeds maximum
"zebra" > "apple"; // true
Less Than or Equal <=¶
Greater Than or Equal >=¶
Equal ==¶
10 == 10; // true
"hello" == "hello"; // true
true == true; // true
null == null; // true
// No type coercion
10 == "10"; // false (different types)
true == 1; // false
Not Equal !=¶
Comparison Examples¶
// Numeric comparison
age = 25;
isYoung = age < 30; // true
isSenior = age >= 65; // false
// String comparison (lexicographic)
name = "Bob";
comesFirst = name < "Charlie"; // true
isAlice = name == "Alice"; // false
// Date comparison
today = $Today();
future = $AddDays(today, 7);
isPast = today > future; // false
isFuture = future > today; // true
// Null comparison
value = null;
isEmpty = value == null; // true
hasValue = value != null; // false
Logical Operators¶
Logical AND &&¶
Returns true only if both operands are true:
true && true; // true
true && false; // false
false && false; // false
// Practical examples
isEligible = age >= 18 && hasLicense;
canProceed = !hasErrors && dataValid && userConfirmed;
Short-circuit evaluation: If left side is false, right side is NOT evaluated:
// Safe: person.age only accessed if person is not null
if (person != null && person.age > 18) {
// ...
}
// Optimization: expensive check only if needed
if (quickCheck && expensiveFunction()) {
// expensiveFunction() only called if quickCheck is true
}
Logical OR ||¶
Returns true if at least one operand is true:
true || false; // true
false || true; // true
false || false; // false
// Practical examples
isValid = hasEmail || hasPhone;
needsReview = isHighRisk || isLargeAmount || hasSpecialConditions;
Short-circuit evaluation: If left side is true, right side is NOT evaluated:
// Default value pattern
useDefault = config == null || config.value == null;
// Skip expensive check if simple check passes
if (isCached || loadFromDatabase()) {
// loadFromDatabase() only called if NOT cached
}
Logical NOT !¶
Inverts a boolean value:
!true; // false
!false; // true
// Practical examples
isInactive = !isActive;
hasErrors = !isValid;
isEmpty = !(array.Length > 0);
// Double negation (convert to boolean, rarely needed in EverSharp)
!!value; // Same as value if already boolean
Combining Logical Operators¶
// Complex conditions
isEligible =
age >= 18 && age <= 65 && (hasLicense || hasPermit) && !isBlacklisted;
// With parentheses for clarity
qualified =
(income > 50000 || hasAssets) && creditScore > 650 && !hasBankruptcy;
// De Morgan's laws
!(a && b); // Equivalent to: !a || !b
!(a || b); // Equivalent to: !a && !b
Assignment Operators¶
Simple Assignment =¶
x = 10;
name = "John";
active = true;
// Assignment returns the value
a = b = c = 10; // All set to 10 (right-to-left)
Compound Assignment¶
Add-Assign +=¶
x = 10;
x += 5; // x = 15 (equivalent to: x = x + 5)
// String concatenation
message = "Hello";
message += " World"; // "Hello World"
// Common pattern
total += itemPrice;
Subtract-Assign -=¶
Multiply-Assign *=¶
Divide-Assign /=¶
Modulo-Assign %=¶
Postfix Operators¶
Post-Increment ++¶
Returns current value, then increments:
counter = 5;
old = counter++; // old = 5, counter = 6
// Common in loops
i = 0;
while (i < 10) {
$Log(i);
i++; // Increment after each iteration
}
Post-Decrement --¶
Returns current value, then decrements:
Note: No prefix versions (++x or --x) exist in EverSharp.
Ternary Operator ?:¶
Conditional expression: condition ? valueIfTrue : valueIfFalse
// Simple conditional
age = 20;
status = age >= 18 ? "Adult" : "Minor"; // "Adult"
// Assign different values
discount = isPremium ? 0.2 : 0.1;
// In calculations
premium = basePremium * (age > 65 ? 1.25 : 1.0);
// With expressions
max = a > b ? a : b;
min = a < b ? a : b;
// Nested (use sparingly for readability)
rate = age < 25 ? 0.15 : age < 65 ? 0.1 : 0.12;
// Better: use if-else for complex logic
if (age < 25) {
rate = 0.15;
} else if (age < 65) {
rate = 0.1;
} else {
rate = 0.12;
}
Member Access Operator .¶
Accesses object properties or calls methods:
// Property access
name = person.name;
premium = policy.premium;
// Nested access
city = customer.address.city;
// Method calls
upper = text.ToUpper();
filtered = array.Filter((x) => x > 10);
// Assignment
person.age = 31;
policy.status = "active";
Array Access Operator []¶
Accesses array elements by index:
numbers = [10, 20, 30, 40, 50];
// Read
first = numbers[0]; // 10
third = numbers[2]; // 30
// Write
numbers[1] = 99; // [10, 99, 30, 40, 50]
// Dynamic index
index = 3;
value = numbers[index]; // 40
// Last element
last = numbers[numbers.Length - 1]; // 50
Grouping Operator ()¶
Overrides default precedence:
// Without parentheses (multiplication first)
result = 2 + 3 * 4; // 14
// With parentheses (addition first)
result = (2 + 3) * 4; // 20
// Complex expressions
average = (a + b + c) / 3;
adjusted = base * rate + fee;
// Logical grouping
if ((age >= 18 && age <= 25) || hasSpecialPermit) {
// ...
}
Operator Precedence Examples¶
Example 1: Arithmetic¶
// Without parentheses
result = 2 + 3 * 4; // 14 (multiply first)
result = 10 - 2 + 3; // 11 (left-to-right)
result = (10 / 2) * 3; // 15 (left-to-right)
// With parentheses
result = (2 + 3) * 4; // 20
result = 10 - (2 + 3); // 5
result = 10 / (2 * 3); // 1.666...
Example 2: Comparison and Logical¶
// Comparison before logical
result = x > 5 && y < 10; // Comparisons evaluated first
// Requires parentheses for clarity
result = x > 5 && y < 10; // Same, but clearer
// AND before OR
result = a || (b && c); // Equivalent to: a || (b && c)
result = (a || b) && c; // Different: both a or b, AND c
Example 3: Assignment¶
// Assignment has lowest precedence
x = y + 5; // Addition first, then assignment
// Compound assignment
x += y * 2; // Equivalent to: x = x + (y * 2)
// Chained assignment (right-to-left)
a = b = c = 10; // c=10, then b=10, then a=10
Example 4: Complex Expression¶
// Step-by-step evaluation
result = 10 + 5 * 2 - 3 / 3;
// Order of operations:
// 1. 5 * 2 = 10
// 2. 3 / 3 = 1
// 3. 10 + 10 = 20
// 4. 20 - 1 = 19
// Result: 19
// With parentheses for different result
result = ((10 + 5) * 2 - 3) / 3; // ((15) * 2 - 3) / 3 = 27 / 3 = 9
Common Patterns¶
Pattern 1: Range Checking¶
// Check if value is in range
inRange = value >= min && value <= max;
inRange = $IsInRange(value, min, max); // Built-in function
// Check if outside range
outOfRange = value < min || value > max;
Pattern 2: Null-Safe Access¶
// Check null before accessing
if (object != null && object.property != null) {
value = object.property.value;
}
// Default value pattern
displayName = name != null ? name : "Unknown";
Pattern 3: Clamping Values¶
// Clamp to range using ternary
clamped = value < min ? min : value > max ? max : value;
// Using $Max and $Min
clamped = $Min($Max(value, min), max);
Pattern 4: Flag Checking¶
// Check multiple flags
allSet = flag1 && flag2 && flag3;
anySet = flag1 || flag2 || flag3;
noneSet = !flag1 && !flag2 && !flag3;
// Toggle flag
flag = !flag;
Pattern 5: Conditional Accumulation¶
total = 0;
total += baseAmount;
total += includeTax ? taxAmount : 0;
total += includeShipping ? shippingCost : 0;
total -= hasDiscount ? discountAmount : 0;
Type Requirements¶
Different operators have different type requirements:
| Operator | Allowed Types | Result Type |
| ----------------- | ----------------------------- | ---------------- | ----------------- | ------- |
| + | number + number, string + any | number or string |
| - * / % | number + number | number |
| < > <= >= | same types | boolean |
| == != | any types | boolean |
| && | | ! | boolean + boolean | boolean |
| = += etc. | any (matching) | assigned type |
Type errors:
// ERROR: Cannot multiply string and number
result = "5" * 10;
// CORRECT: Convert first
result = "5".ToNumber() * 10; // 50
// ERROR: Cannot use number as boolean
// if (count) { }
// CORRECT: Compare explicitly
if (count > 0) {
}
Best Practices¶
- Use parentheses for clarity: Even when not required
- Avoid complex nested ternaries: Use if-else instead
// Hard to read
value = a ? (b ? c : d) : e ? f : g;
// Better
if (a) {
value = b ? c : d;
} else {
value = e ? f : g;
}
- Check for null before property access:
- Use compound assignment for clarity:
- Be explicit with boolean conditions:
// Prefer
if (count > 0) {
}
if (name != null && name != "") {
}
// Over (would be errors in EverSharp anyway)
// if (count) { }
// if (name) { }
Next Steps¶
- Learn control flow: Control Flow
- Explore functions: Functions
- See examples: Basic Calculations