Operators
Reviewed & published by Brayan K
By the end of this lesson you'll be able to do maths in C#, compare values, combine conditions with AND/OR, write compact decisions with the ternary operator, and handle missing (null) values safely — the toolkit every decision in your programs is built from.
Part of the free C# course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.
What You'll Learn
- Use arithmetic operators (+, -, *, /, %) and understand integer division
- Apply increment (++), decrement (--), and compound assignment (+=, -=, *=)
- Compare values with ==, !=, >, <, >=, <= and know they return bool
- Combine conditions with logical operators (&&, ||, !)
- Use the ternary operator (? :) for concise conditional values
- Handle null values safely with ??, ??=, and ?.
💡 Real-World Analogy
Operators are the buttons on a calculator. Arithmetic operators (+, -, ×, ÷) do maths. Comparison operators are a referee making yes/no calls — "Is player A's score higher than player B's?" Logical operators are how you combine conditions on a checklist: "Do I have BOTH a passport AND a visa?" (&&) or "Do I have EITHER cash OR a card?" (||). The ternary operator is the quick "if yes do this, otherwise do that" sticky note. Master these and you can express almost any decision a program needs to make.
📊 Operator Precedence (who goes first)
Like maths, C# evaluates some operators before others. Higher priority happens first; () always wins, so when in doubt, add brackets.
| Priority | Operators | Meaning |
|---|---|---|
| 1 (Highest) | () ?. ! | Parentheses, null-conditional, not |
| 2 | * / % | Multiply, divide, remainder |
| 3 | + - | Add, subtract |
| 4 | < > <= >= | Comparison |
| 5 | == != | Equality |
| 6 | && | Logical AND |
| 7 | || | Logical OR |
| 8 | ?: | Ternary |
| 9 (Lowest) | = += -= *= ??= | Assignment |
1. Arithmetic Operators
Arithmetic operators do the maths: +, -, *, /, and % (remainder). The one that trips up every beginner is integer division: when both numbers are whole, 10 / 3 gives 3 — the decimal part is thrown away, not rounded. The % operator gives you what's left over (handy for "is this even?"). For tidy updates, ++/-- change a value by one, and compound operators like += mean "add to what's already there". Read this worked example, run it, then you'll write your own.
using System;
class Program
{
static void Main()
{
int a = 10, b = 3;
// Basic arithmetic — each line states its result on the right.
Console.WriteLine($"a + b = {a + b}"); // 13
Console.WriteLine($"a - b = {a - b}"); // 7
Console.WriteLine($"a * b = {a * b}"); // 30
Console.WriteLine($"a / b = {a / b}"); // 3 (integer division — decimals dropped!)
Console.WriteLine($"a % b = {a % b}"); // 1 (% is the REMAINDER after dividing)
// Increment (++) and decrement (--) change a value by 1.
int x = 5;
Console.WriteLine($"x++ = {x++}"); // 5 (uses the OLD value, THEN adds 1)
Console.WriteLine($"x is now {x}"); // 6
Console.WriteLine($"++x = {++x}"); // 7 (adds 1 FIRST, then uses it)
// Compound assignment — a shorthand that updates a variable in place.
int score = 100;
score += 50; // score = score + 50 -> 150
score -= 20; // score = score - 20 -> 130
score *= 2; // score = score * 2 -> 260
Console.WriteLine($"Final score: {score}"); // Final score: 260
}
}
// ✅ Expected output:
// a + b = 13
// a - b = 7
// a * b = 30
// a / b = 3
// a % b = 1
// x++ = 5
// x is now 6
// ++x = 7
// Final score: 260Your turn. The program below tallies a shopping basket — fill in the four blanks marked ___ using the hints, then run it and check the expected output.
using System;
class Program
{
static void Main()
{
// 🎯 YOUR TURN — replace each ___ then press "Try it Yourself".
// You're totalling up a shopping basket.
int applesPrice = 3; // £ each
int breadPrice = 2; // £ each
int milkPrice = 1; // £ each
// 1) Start a running total at 0
int total = ___; // 👉 the starting amount, a whole number
// 2) Add each item to the total using +=
total += applesPrice; // total is now 3
total ___ breadPrice; // 👉 use the same compound operator (+=)
total += milkPrice; // total is now 6
// 3) Work out the average price with division (3 items)
int average = total / ___; // 👉 how many items? a whole number
Console.WriteLine($"Basket total: £{total}"); // expect £6
Console.WriteLine($"Average item: £{average}"); // expect £2
// ✅ Expected output:
// Basket total: £6
// Average item: £2
}
}2. Comparison & Logical Operators
A comparison asks a yes/no question and gives back a bool — true or false. You have == (equal), != (not equal), and < > <= >=. Logical operators glue those answers together: && (AND) is true only when both sides are true, || (OR) is true when at least one side is, and ! (NOT) flips a value. These are the foundation of every if statement you'll write next lesson.
using System;
class Program
{
static void Main()
{
// Comparison operators always return a bool (true / false).
int age = 20;
Console.WriteLine($"age == 20: {age == 20}"); // true (== means "equal to")
Console.WriteLine($"age != 18: {age != 18}"); // true (!= means "not equal")
Console.WriteLine($"age > 18: {age > 18}"); // true
Console.WriteLine($"age <= 21: {age <= 21}"); // true
// Logical operators combine bool values.
bool hasTicket = true;
bool isVIP = false;
// && (AND) — true only when BOTH sides are true.
Console.WriteLine($"Can enter VIP: {hasTicket && isVIP}"); // false
// || (OR) — true when AT LEAST ONE side is true.
Console.WriteLine($"Can enter event: {hasTicket || isVIP}"); // true
// ! (NOT) — flips true to false and vice versa.
Console.WriteLine($"No ticket: {!hasTicket}"); // false
// Combine comparisons with && to make a range check.
int temp = 22;
bool isComfortable = temp >= 18 && temp <= 26;
Console.WriteLine($"Comfortable temp: {isComfortable}"); // true
}
}
// ✅ Expected output:
// age == 20: True
// age != 18: True
// age > 18: True
// age <= 21: True
// Can enter VIP: False
// Can enter event: True
// No ticket: False
// Comfortable temp: TrueNow you build a real rule. A ride needs the person to be old enough and tall enough — both must pass. Fill in the three blanks:
using System;
class Program
{
static void Main()
{
// 🎯 YOUR TURN — a theme-park ride has TWO rules:
// you must be at least 12 years old AND at least 140 cm tall.
int age = 13;
int heightCm = 145;
// 1) Is the person old enough? (12 or over)
bool oldEnough = age >= ___; // 👉 the minimum age, a whole number
// 2) Is the person tall enough? (140 or over)
bool tallEnough = heightCm ___ 140; // 👉 the "greater than or equal" operator (>=)
// 3) BOTH rules must pass — combine them with AND
bool canRide = oldEnough ___ tallEnough; // 👉 the logical AND operator (&&)
Console.WriteLine($"Old enough? {oldEnough}"); // expect True
Console.WriteLine($"Tall enough? {tallEnough}"); // expect True
Console.WriteLine($"Can ride? {canRide}"); // expect True
// ✅ Expected output:
// Old enough? True
// Tall enough? True
// Can ride? True
}
}3. Ternary & Null-Safe Operators
The ternary operator condition ? a : b is a one-line if/else that produces a value: "if the condition is true use a, otherwise b". C# also has null-safe operators for values that might be missing: ?? supplies a fallback when something is null, ??= assigns only if the variable is currently null, and ?. reads a member without crashing on null. (A null value means "nothing here yet" — reading from it directly throws a NullReferenceException, the most common runtime crash in C#.)
using System;
class Program
{
static void Main()
{
// Ternary operator: condition ? valueIfTrue : valueIfFalse
// It's a one-line if/else that PRODUCES a value.
int age = 20;
string status = age >= 18 ? "Adult" : "Minor";
Console.WriteLine($"Status: {status}"); // Status: Adult
// Null-coalescing (??) — "use the left side, or this fallback if it's null".
string? userName = null;
string displayName = userName ?? "Guest";
Console.WriteLine($"Welcome, {displayName}!"); // Welcome, Guest!
userName = "Alice";
displayName = userName ?? "Guest";
Console.WriteLine($"Welcome, {displayName}!"); // Welcome, Alice!
// Null-coalescing assignment (??=) — assign ONLY if currently null.
string? city = null;
city ??= "London"; // city was null, so it becomes "London"
Console.WriteLine($"City: {city}"); // City: London
// Null-conditional (?.) — read a member safely; null instead of a crash.
string? text = null;
int? length = text?.Length; // null (no NullReferenceException)
Console.WriteLine($"Length: {length ?? 0}"); // Length: 0
}
}
// ✅ Expected output:
// Status: Adult
// Welcome, Guest!
// Welcome, Alice!
// City: London
// Length: 0🔎 Deep Dive: short-circuiting & precedence
Short-circuit evaluation means C# stops the moment the answer is certain. With &&, if the left side is false the whole thing is false, so the right side is never run. With ||, if the left side is true the right side is skipped. This is not just an optimisation — you rely on it to stay safe, e.g. order != null && order.Total > 0 only touches order.Total once you know order isn't null.
Precedence decides who runs first when you don't add brackets. * and / beat + and - (just like maths), comparisons beat &&, and && beats ||. When a line gets busy, brackets make your intent obvious and remove all doubt.
int total = 2 + 3 * 4; // 14 (3*4 first, THEN +2 — not 20)
bool ok = 5 > 3 && 2 > 1; // true (each > runs before &&)
bool a = true || Crash(); // true (Crash() never runs — short-circuit)
bool b = (1 + 2) * 3 == 9; // true (() forces the add to go first)Putting It Together: a Ticket Pricer
Here's a small but real program that uses arithmetic (%), comparison, logical OR, and a chained ternary together. Read it line by line — you understand every operator in it now.
using System;
class Program
{
static void Main()
{
// === Cinema ticket price — combines this lesson's operators ===
int age = 15;
bool isStudent = true;
// % (remainder) tells us if a number is even: even numbers leave 0.
int seat = 24;
string seatType = seat % 2 == 0 ? "aisle" : "window"; // "aisle"
// Pick a price with a ternary chain (read top to bottom).
// Under 13 = £6, 13–17 OR a student = £8, otherwise £12.
decimal price = age < 13 ? 6m
: age < 18 || isStudent ? 8m
: 12m; // 8m here
Console.WriteLine($"Seat {seat} is an {seatType} seat"); // Seat 24 is an aisle seat
Console.WriteLine($"Ticket price: £{price}"); // Ticket price: £8
}
}
// ✅ Expected output:
// Seat 24 is an aisle seat
// Ticket price: £8A chained ternary reads like a ladder: the first matching condition wins. age < 13 ? 6m : age < 18 || isStudent ? 8m : 12m checks youngest first, then teen-or-student, then falls through to the standard price.
Pro Tips
- 💡 Use parentheses for clarity: even when precedence is correct, (a > 5) && (b < 10) reads more clearly than a > 5 && b < 10.
- 💡 Prefer ?? over an if-null check: string name = input ?? "default"; is cleaner than a 4-line if/else.
- 💡 Short-circuit evaluation: && stops at the first false and || stops at the first true. Put the cheap or most-likely-to-decide check first.
- 💡 Use % for "every Nth": i % 2 == 0 is even; i % 5 == 0 is every fifth item.
- 💡 Chain ?. for nested data: user?.Address?.City returns null safely instead of crashing.
Common Errors (and the fix)
- "CS0029: Cannot implicitly convert type 'int' to 'bool'": you wrote = (assign) where you meant == (compare). if (x = 5) is wrong; use if (x == 5).
- Integer division surprise: 7 / 2 gives 3, not 3.5. Make one side a decimal: (double)7 / 2 or 7.0 / 2 → 3.5.
- Confusing ++ placement: x++ uses the old value then adds 1; ++x adds 1 first. They print different things inside an expression.
- "CS0019: Operator '<' cannot be applied": you tried to chain comparisons like maths — 1 < x < 10 doesn't compile. Write x > 1 && x < 10.
- "CS8602: Dereference of a possibly null reference": you read .Length on something that might be null. Use text?.Length or give a fallback with ?? — don't silence it with !.
📋 Quick Reference
| Operator | Does | Example | Result |
|---|---|---|---|
| % | Remainder | 7 % 2 | 1 |
| / | Integer divide | 7 / 2 | 3 |
| += | Add & assign | n += 5 | n grows by 5 |
| == | Equal? | 3 == 3 | true |
| && | AND (both) | true && false | false |
| || | OR (either) | true || false | true |
| ?: | Ternary | x > 0 ? "+" : "-" | "+" or "-" |
| ?? | Null fallback | name ?? "Guest" | name or "Guest" |
Frequently Asked Questions
Q: Why did 10 / 3 give me 3 instead of 3.33?
Both numbers are int, so C# does integer division and drops the remainder. Make one side a decimal type — 10.0 / 3 or (double)10 / 3 → 3.333....
Q: What's the difference between = and ==?
One = assigns a value (x = 5 puts 5 into x). Two == compares and returns a bool (x == 5 asks "is x equal to 5?"). Using = in an if is a classic bug — C# usually catches it with a compile error.
Q: When should I use the ternary operator instead of an if/else?
Use the ternary when you're choosing a value in one short expression, like age >= 18 ? "Adult" : "Minor". If the branches do several things or get long, a full if/else stays more readable.
Q: What does % actually do, and why is it useful?
It gives the remainder after division. 7 % 2 is 1. The classic trick is n % 2 == 0 to test if a number is even, or i % 10 == 0 to do something every tenth time.
Mini-Challenge: Even or Odd?
No blanks this time — just a brief and a blank canvas (with an outline to keep you on track). Combine the remainder operator % with a ternary to decide the answer, run it, and check your output against the examples in the comments.
using System;
class Program
{
static void Main()
{
// 🎯 MINI-CHALLENGE: Even or odd?
// 1. Create an int "number" set to any whole number (try 7, then 10).
// 2. Use the remainder operator % -> number % 2 is 0 for even numbers.
// 3. Use a TERNARY to pick the word "even" or "odd".
// 4. Print: "7 is odd" (using your number and the chosen word).
//
// ✅ Expected (number = 7): 7 is odd
// ✅ Expected (number = 10): 10 is even
// your code here
}
}🎉 Lesson Complete
- ✅ Arithmetic: +, -, *, /, % — and integer division truncates
- ✅ Increment/decrement: x++ (post) vs ++x (pre) return different values
- ✅ Compound assignment: +=, -=, *= update a variable in place
- ✅ Comparison operators return bool: ==, !=, >, <, >=, <=
- ✅ Logical: && (AND), || (OR), ! (NOT) — with short-circuiting
- ✅ Ternary condition ? a : b; null-safe ??, ??=, ?.
Practice quiz
What does the % (remainder) operator give for 7 % 2 ?
- 3
- 0
- 1
- 3.5
Answer: 1. % returns the remainder after dividing; 7 divided by 2 leaves 1.
What is the value of 10 / 3 when both are int?
- 3
- 3.33
- 4
- 3.0
Answer: 3. Integer division drops the decimal part, so 10 / 3 is 3.
What does the expression true && false evaluate to?
- true
- an error
- null
- false
Answer: false. && (AND) is true only when both sides are true; here one side is false, so the result is false.
Which operator is logical OR — true when at least one side is true?
- &&
- ||
- !
- ==
Answer: ||. || (OR) is true when at least one operand is true.
What is the difference between = and == ?
- = assigns a value, == compares for equality
- They are identical
- = compares, == assigns
- == assigns, = compares
Answer: = assigns a value, == compares for equality. A single = assigns; a double == compares two values and returns a bool.
For int x = 5; what does the expression x++ evaluate to?
- 6
- 4
- 5
- an error
Answer: 5. Post-increment x++ uses the OLD value (5) in the expression, then adds 1 afterwards.
What does the null-coalescing expression null ?? "Guest" produce?
- null
- "Guest"
- an error
- false
Answer: "Guest". ?? returns the left side unless it is null, in which case it returns the fallback "Guest".
What does the ternary age >= 18 ? "Adult" : "Minor" return when age is 20?
- "Minor"
- true
- 20
- "Adult"
Answer: "Adult". 20 >= 18 is true, so the ternary yields the first value, "Adult".
With short-circuit evaluation, in false && Something() what happens?
- Something() always runs
- Something() is never run
- It throws an error
- It returns true
Answer: Something() is never run. && stops as soon as the left side is false, so the right side (Something()) is never evaluated.
In 2 + 3 * 4 , which operation happens first by precedence?
- 2 + 3
- left to right always
- 3 * 4
- 4 + 2
Answer: 3 * 4. * has higher precedence than +, so 3 * 4 runs first, giving 2 + 12 = 14.
Continue this course
- Previous: Checkpoint: Types & Data
- Next: Control Flow — Control your program's logic with if, else, switch, and ternary expressions
- Quick reference: C# cheat sheet