if
statement allows a statement to only run when the conditions are right: if (condition) Console.WriteLine("It's happening!");
{ statement1; statement2; }
if
needs to guard many statements.if
statement’s condition is false
, use an else
: if (condition) Console.WriteLine("It's happening!"); else Console.WriteLine("It didn't happen.");
if
statements:==
to check for equality.!=
to check for inequality.<
to check if the left side is less than the right side.>
to check if the left side is greater than the right side.<=
to check if the left side is less than or equal to the right side.>=
to check if the left side is greater than or equal to the right side.!
(not) inverses a Boolean expression.&&
(and) is true
only if both sides are both true
.||
(or) is true
if either side is true
(and false
if neither are).In the Hello World tutorial, we talked about how the flow of execution generally works from top to bottom, one statement at a time. In the next few tutorials, we’ll see some tools to allow more than just executing statements one after the next.
In this tutorial, we’ll look at ways to skip certain statements, based on the state of variables in our code, allowing us to make decisions and follow alternate paths.
if
statementImagine you are making a game where, depending on how many points the player gets in a level, they earn stars.
Let’s say we’ve been tracking the score as the game progressed, and now it is time to decide how many stars to give for any given point total.
Let’s suppose that we give out three stars (the most possible) only if they score a perfect 2000, two stars if they score more than 1500, one star is they score more than 1000, and no stars if they score less than that.
It is easy to imagine the basic setup. We’ll need a variable to store the number of points (and we’ll ignore how this gets decided right now). We’ll also need a variable to store the number of stars they’ve earned.
int points = 1560;
int stars = 0; // We'll initialize to zero for now, and change it later.
But how do we build code that will determine the right number of stars?
The if
statement is our primary tool for decision making in C#.
This is easier to show than describe, so here is a simple example of an if
statement:
if (points == 2000)
stars = 3;
You could read this aloud as “If points
equals 2000
, then stars
is assigned a value of 3
.”
Each if statement starts with theif
keyword, followed by a set of parentheses that contains some sort of expression whose type is bool
.
The ==
operator is but one of many types of operators that is used in an if
statement, but it is an important one.
It evaluates to true
if the thing on each side are equal to each other, and it evaluates to false
if they are not equal.
If the condition is true, the statement following the if
statement will run.
Otherwise it will not.
The indentation above (bringing the statement guarded by the if
inward with a tab or several spaces) makes it clear that this stars = 3;
statement only runs sometimes.
Whitespace does not matter in C#, so a second style that is common for if
statements is this:
if (points == 2000) stars = 3;
The following is legal, but I’d strongly discourage it:
if (points == 2000)
stars = 3;
With that code, it is easy to accidentally assume that stars = 30;
runs always, when it does not.
So what happens when you need to guard multiple statements with an if
?
Do you just do this?
if (points == 2000) stars = 3;
if (points == 2000) Console.WriteLine("A perfect score!");
That technically works, but isn’t very clean or easy to maintain. There is a better way.
C# has a concept called a block statement
.
A block statement is a way to bundle many statements together, and use them anywhere a single statement is allowed.
You form a block by using a set of curly braces ({
and }
):
{
stars = 3;
Console.WriteLine("A perfect score!");
}
Block statements like this are very often combined with if
statements, and are the most convenient way to protect many statements inside an if
:
if (points == 2000)
{
stars = 3;
Console.WriteLine("A perfect score!");
}
In fact, some people prefer just always using a block statement with an if
.
They’ll use the curly braces even if there is only one statement.
While it is not necessary, it does have the effect of reducing the chances of accidentally thinking a statement is protected by the if
when it isn’t:
if (points == 2000)
stars = 3;
Console.WriteLine("A perfect score!");
In the code above, only the stars = 30;
statement is ran conditionally.
The Console.WriteLine
will happen every time.
By using the curly braces, you reduce the chances of accidentally misinterpreting something as being part of an if
statement when it actually isn’t.
else
StatementsThe else
statement is if
’s counterpart.
An else
statement is used in conjunction with an if
to say, “Well if the condition isn’t right for the if
, then do this other stuff instead.”
For example:
if (points == 2000)
Console.WriteLine("A perfect score!");
else
Console.WriteLine("Good work, but you still have room for improvement!");
An else
statement, can also use a block:
if (points == 2000)
{
stars = 3;
Console.Writeline("A perfect score!");
}
else
{
stars = 0;
Console.WriteLine("Good work, but you still have room for improvement!");
}
if
/else
StatementsAnother common tactic is to chain many if
and else
statements together.
This is useful when you have several buckets that things can land in, rather than just one or two.
Let’s assume, for a second, that we’ve already figured out how to determine if the player gets 0, 1, 2, or 3 stars (we’re still coming to that), and want to just display some text in response:
if (stars == 0)
Console.WriteLine("Try again!");
else if (stars == 1)
Console.WriteLine("Nice!");
else if (stars == 2)
Console.WriteLine("Fantastic!");
else
Console.WriteLine("Perfection!");
There is no limit to how many you can string together. And, of course, you can use a block statement in any or all of the above if you want or have the need.
==
, !=
, <
, >
, <=
, and >=
While we’ve seen that ==
is used to check if two things are exactly equal, there are other similar operators that we should know.
The !=
operator is the opposite of ==
, and tells you if two things are not equal to each other.
if (score != 0)
Console.WriteLine("It could have been worse!");
The <
operator is the “less than” operator, and tells you if the thing on the left is less than the thing on the right.
Similarly, the >
operator is the “greater than” operator, and tells you if the thing on the left is greater than the thing on the right.
note
While ==
and !=
work on most types, including string
, the <
and >
operators are more limited, and only work on numbers and things that have a distinct ordering.
if (score > 1500)
stars = 2;
This will store a value of 2
into stars
, but only if the score is more than 1500.
But wait!
Our original description said, “You get two stars if you score at least 1500.”
In this case, 1500 actually wouldn’t get two stars.
We could change the if
statement’s condition to say if (score > 1499)
, there’s a better way.
The <=
operator checks if the thing on the left is less than or equal to the thing on the right, while >=
checks if the thing on the left is greater than or equal to the thing on the right.
So a better check would be:
if (score >= 1500)
stars = 2;
At this point, we have enough tools in our arsenal to actually write out a solution to our problem of awarding stars based on points:
int points = 1560;
int stars;
if (points == 2000)
stars = 3;
else if (points >= 1500)
stars = 2;
else if (points >= 1000)
stars = 1;
else
stars = 0;
Remember, the order matters here.
The way this code is structured, we’ll only land in one of these categories.
(If we just made separate if
statements without else
s, then we could land in multiple categories.)
If we rearrange the order, we’ll get different (and incorrect, in this case) results.
bool
TypeThe bool
type is especially important in decision making.
As we have seen, the condition of an if
statement must be an expression of the type bool
.
There are two notable things that come out of that.
The first is that we could use a bool
variable directly in an if
statement:
bool hasBeatenLevel = true;
if (hasBeatenLevel)
{
Console.WriteLine("You beat the level!");
currentLevel++;
}
Second (and related), these expressions whose type is bool
can be stored in a bool
variable whenever that is needed or desirable:
bool hasBeatenLevel = score >= requiredPoints;
if (hasBeatenLevel)
{
// ...
}
This can help break apart complicated expressions into smaller parts.
There are a few other operators that make it easy to build complicated Boolean expressions.
First, the !
operator (the not operator) is used to invert any other Boolean expression.
What was true
becomes false
.
What was false
becomes true
.
bool hasBeatenLevel = score >= requiredPoints;
bool hasFailedLevel = !hasBeatenLevel;
The &&
operator (the and operator) and the ||
operator (the or operator) are used to combine two other Boolean expressions.
&&
evaluates to true
if both sides are true
(and false
if both or either are false
).
||
evaluates to true
only if either side is true
(including if both sides are true
).
if (killCount >= 10 && score >= 1000)
Console.WriteLine("You killed at least 10 enemies and scored at least 1000 points, so you beat the level!");
if (killCount < 10 || score < 1000)
Console.WriteLine("Either you didn't kill enough enemies or didn't score enough points (or both) to make it past this level.");
These operators are called conditional operators and can be combined in as long of chains as you need.
An if
statement can contain any statement it wants, and that includes another if
statement:
if (killCount >= 10)
{
if (score >= 1000) Console.WriteLine("You killed enough enemies and scored enough points to advance!");
else Console.WriteLine("You killed enough enemies, but did not score enough points to advance.");
}
When you put something inside another of the same type, it is called nesting
.
You could say that the above code has a nested if
statement.
You can nest if
statements as deeply as you have a need for, but keep in mind that deep nesting can make code hard to understand.