1. Expressions vs Statements
In C#, all commands are split into two categories: statements (Statement) and expressions (Expression). People usually say a statement is executed, and an expression is evaluated. But that's not the main thing.
The main difference: an expression has a result. That result has a type, and you can assign it to a variable or use it in another expression.
Examples:
| Code | Notes |
|---|---|
|
Statement |
|
Expression, type bool |
|
Expression, type matches variable i |
|
Expression, type matches variable x |
So what does this give us?
A lot of statements are actually expressions (they have a result). For example, this code works:int x, y, z;
x = y = z = 1; // x = (y = (z = 1));
You can ignore the result of an expression if you don't need it:
Console.ReadLine(); // ignoring the input result
That's handy if the expression does something useful besides returning a result (like printing to the screen or reading input).
2. The Ternary Operator
C# has a special ternary (triple) operator. It's like a shorthand for the if–else operator:
Condition ? Expression1 : Expression2;
If Condition is true, Expression1 is evaluated, otherwise Expression2 is. After the condition, you put a ?, and the two expressions are separated by a :.
The main difference from if-else: the ternary operator is an expression, so you can assign its result to a variable or use it in other expressions.
For example, let's get the minimum of two numbers:
int a = 2;
int b = 3;
int min = a < b ? a : b;
Or assign different values to a variable depending on a condition:
int age = 25;
int money;
if (age > 30)
money = 100;
else
money = 50;
Same thing with the ternary operator:
int age = 25;
int money = age > 30 ? 100 : 50;
Which should you use: if-else or the ternary operator? There's no speed difference, but the ternary operator is great for short conditions. If your code doesn't fit on one line, it's better to use if-else for readability.
3. How It Works: Gotchas
Value types
Both branches of the ternary operator (<value_if_true> and <value_if_false>) have to be the same type or compatible (like both string or both int).
Works:
int a = 10, b = 20;
int max = (a > b) ? a : b; // both branches are int
Compilation error:
int a = 10, b = 20;
// string and int are not compatible
string result = (a > b) ? "greater" : 0; // Compilation error
Correct version:
int a = 10, b = 20;
string result = (a > b) ? "greater" : "less or equal";
Example: working with numbers
int number = -5;
int abs = (number >= 0) ? number : -number;
Console.WriteLine(abs); // 5
4. Plugging the Ternary Operator into an App
Let's write a little dialog app: besides greeting the user, the program will tell them how old they'll be next year, and whether they'll be an adult.
Console.Write("Enter your name: ");
string name = Console.ReadLine();
Console.Write("Enter your age: ");
string ageText = Console.ReadLine();
int age = int.Parse(ageText);
int nextYear = age + 1;
string status = (nextYear >= 18) ? "adult" : "minor";
Console.WriteLine($"Hi, {name}! Next year you'll be {nextYear}. You'll be {status}.");
Let's break it down:
- The status variable is calculated with the ternary operator: if the age next year is at least 18, the user will be (or stay) an adult.
- You can easily plug the ternary operator right into strings (like with $"" interpolation).
5. Nested Ternary Operators — Careful!
You can nest ternary operators (each branch can have another ternary inside). But... this usually gives you a headache, especially for whoever reads your code after you (even if that's you in 2 days).
Example: figuring out category by age
string category = (age < 7) ? "preschooler" :
(age < 18) ? "schoolkid" :
(age < 65) ? "adult" : "retiree";
Decision table:
| Age | Condition | Result |
|---|---|---|
| < 7 | age < 7 | preschooler |
| 7–17 | age < 18 | schoolkid |
| 18–64 | age < 65 | adult |
| 65 and up | else | retiree |
You can still read code like this, but if the logic gets more complicated — it's better to use if-else if-else.
6. Lifehack: Ternary Operator and bool Type
Sometimes you'll see code like this:
bool adult = (age >= 18) ? true : false;
But that's overkill. The expression (age >= 18) already returns a bool. So you can just write:
bool adult = (age >= 18);
GO TO FULL VERSION