Comparison and logic
Arithmetic answers with a number, but a program often needs a "yes" or "no" answer. Is there enough money for the purchase? Is the user 18 yet? Comparison operators ask such questions.
Imagine an attendant at the door of a screening of an 18+ film. They look at a passport and answer one question for themselves: is the viewer 18 yet? There are only two answers: let them in or not. In C# such an answer has the type bool: true or false.
int age = 20;
Console.WriteLine(age >= 18); // True
Console.WriteLine(age == 18); // False
Console.WriteLine(age != 18); // True
bool isAdult = age >= 18;
Console.WriteLine(isAdult); // TrueLet's go through the program line by line:
age >= 18asks "is the age at least 18?"—yes, so it printsTrue.age == 18asks "is the age exactly 18?"—no, so it printsFalse.age != 18asks "is the age not 18?"—yes, so it printsTrue.- The result of a comparison can go into a
boolvariable, like any other value.
In code the values are written in lowercase, true and false, while Console.WriteLine prints them capitalized: True and False.
Comparison operators
C# can ask six questions:
==—equal to;!=—not equal to;<—less than;>—greater than;<=—less than or equal to;>=—greater than or equal to.
A comparison runs after arithmetic: in age + 1 >= 18, age + 1 is computed first.
The equals sign in a comparison is doubled. A single = is assignment. Mixing them up is a common mistake, covered at the end of the lesson.
Logical operators
One question is often not enough. This film lets a viewer in only if they are at least 18 and have a ticket. Logical operators join such questions:
bool hasTicket = false;
bool student = true;
bool pensioner = false;
Console.WriteLine(age >= 18 && hasTicket); // False
Console.WriteLine(student || pensioner); // True
Console.WriteLine(!hasTicket); // True&&—"and"
a && b is true only when both parts are true. The age 20 fits, but there is no ticket, so the first line prints False.
The same way you check that a number lies in a range: age >= 7 && age <= 12. Writing 7 <= age <= 12, as in math, does not compile: the first comparison gives a bool, and a bool is not compared with a number.
||—"or"
a || b is true when at least one part is true. A discount goes to a student or a pensioner. Our viewer is a student, and the line prints True.
!—"not"
!a flips the value: !false is true. There is no ticket, so !hasTicket prints True.
To flip a comparison, put it in parentheses: !(age >= 18). Without them ! would apply to the number age, and the program would not compile.
When one expression has both && and ||, add parentheses. && runs before ||, but with parentheses the order is visible at once.
Short-circuit evaluation
The attendant will not ask a viewer under 18 for a ticket: the answer is already "no". C# does the same. && and || evaluate the left part first, and if it already settles the answer, they do not evaluate the right part at all. This rule is called short-circuit evaluation:
&&skips the right part when the left one isfalse;||skips the right part when the left one istrue.
Dividing an int by zero is an error: the program stops on it. Thanks to short-circuit evaluation, the left part can guard the right one against that error:
int count = 0;
int total = 10;
Console.WriteLine(count > 0 && total / count > 2); // False
Console.WriteLine(count == 0 || total / count > 2); // TrueLet's see why the program does not stop:
count > 0isfalse, and&&does not evaluatetotal / count. There is no division by zero, and the line printsFalse.count == 0istrue, and||does not reach the division either. The line printsTrue.
Here the attendant analogy parts ways with C#. The attendant may start with any question, but C# always evaluates the left part first, so the order of the parts matters. If you write total / count > 2 && count > 0, the division runs before the check, and the program stops with a DivideByZeroException error.
Interviewers like to ask about short-circuit evaluation. They also ask how && differs from &. With bool, the & operator also means "and", but it always evaluates both parts, so count > 0 & total / count > 2 stops the program with the same error.
Common mistake
An assignment is written instead of a comparison—one = sign instead of two:
int age = 20;
bool isEighteen = age = 18; // ✗
Console.WriteLine(isEighteen);error CS0029: Cannot implicitly convert type 'int' to 'bool'The program does not compile. age = 18 puts 18 into age, and the value of the whole expression is the number 18. A number cannot go into a bool variable. A comparison needs two signs: bool isEighteen = age == 18;.
Key points
- The operators
==,!=,<,>,<=and>=compare values and give abool:trueorfalse. &&is true when both parts are true,||when at least one is, and!flips the value.&&and||do not evaluate the right part when the left one settles the answer.- A single
=assigns, a double==compares.