ms_learn_csharp/008_if_else/008_csharp.md

27 KiB
Raw Blame History

Introduction

The C# programming language allows you to build applications that employ decision-making logic.

Suppose you want to display different information to the end user depending on some business rules. For example, what if you want to display a special message on a customer's bill based on their geographic region? What if you want to give a customer a discount based on the size of their order? Or what if you want to display an employee's title based on their level in the company. In each case, you would need to add decision logic.

By the end of this module, you'll be able to write code that can change the flow of your code's execution based on some criteria.

Important
This module includes coding activities that require Visual Studio Code. You'll need access to a development environment that has Visual Studio Code installed and configured for C# application development.

Learning objectives

In this module, you will:

  • Write code that evaluates conditions by using the statements if, else, and else if.
  • Build Boolean expressions to evaluate a condition.
  • Combine Boolean expressions using logical operators.
  • Nest code blocks within other code blocks.

Prerequisites

  • Experience using Visual Studio Code to create and run C# console applications.
  • Experience printing messages to the console using Console.WriteLine().
  • Experience with string interpolation to combine variables into literal strings.
  • Experience working with the System.Random class to generate random numbers.

Exercise

Create decision logic with if statements

Most applications include a large number of execution paths. For example, an application could implement different execution paths based on which menu option a user selects. Developers refer to the code that implements different execution paths as code branches.

The most widely used code branching statement is the if statement. The if statement relies on a Boolean expression that is enclosed in a set of parentheses. If the expression is true, the code after the if statement is executed. If not, the .NET runtime ignores the code and doesn't execute it.

In this exercise, you'll practice writing if statements by creating a game. First you'll define the rules of the game, then you'll implement them in code.

You'll use the Random.Next() method to simulate rolling three six-sided dice. You'll evaluate the rolled values to calculate the score. If the score is greater than an arbitrary total, then you'll display a winning message to the user. If the score is below the cutoff, you'll display a losing message to the user.

  • If any two dice you roll result in the same value, you get two bonus points for rolling doubles.
  • If all three dice you roll result in the same value, you get six bonus points for rolling triples.
  • If the sum of the three dice rolls, plus any point bonuses, is 15 or greate r, you win the game. Otherwise, you lose.

You'll refine the rules as you learn more about the if statement.

Important
This exercise makes extensive use of the System.Random class. You can refer to the Microsoft Learn module titled "Call methods from the .NET Class Library using C#" if you need a refresher how Random.Next() works.

Prepare your coding environment

This module includes activities that guide you through the process of building and running sample code. You're encouraged to complete these activities using Visual Studio Code as your development environment. Using Visual Studio Code for these activities will help you to become more comfortable writing and running code in a developer environment that's used by professionals worldwide.

Open Visual Studio Code.

Write code that generates three random numbers and displays them in output

Ensure that you have an empty Program.cs file open in Visual Studio Code.

To create the initial code for this exercise, enter the following:

Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;

Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

Take a minute to review the code that you entered.

To begin, you create a new instance of the System.Random class and store a reference to the object in a variable named dice. Then, you call the Random.Next() method on the dice object three times, providing both the lower and upper bounds to restrict the possible values between 1 and 6 (the upper bound is exclusive). You save the three random numbers in the variables roll1, roll2, and roll3, respectively.

Next, you sum the three dice rolls and save the value into an integer variable named total.

Finally, you use the WriteLine() method to display the three values using string interpolation.

When you run the code, you should see the following message (the numbers will be different).

Output

Dice roll: 4 + 5 + 2 = 11

This first task was a setup task. Now, you can add the decision logic into your code to make the game more interesting.

Add an if statement to display different messages based on the value of the total variable

In the Visual Studio Code Editor, locate the cursor at the bottom of your code file, and then create a blank code line.

To create your first game feature, enter the following if statements.

if (total > 14){
    Console.WriteLine("You win!");
}

if (total < 15){
    Console.WriteLine("Sorry, you lose.");
}

These two if statements are used to handle the winning and losing scenarios. Take a minute to examine the first if statement.

Notice that the if statement is made up of three parts:

  • The if keyword
  • A Boolean expression between parenthesis ()
  • A code block defined by curly braces { }

At run time, the Boolean expression total > 14 is evaluated. If this is a true statement (if the value of total is greater than 14) then the flow of execution will continue into the code defined in the code block. In other word s, it will execute the code in the curly braces.

However, if the Boolean expression is false (the value of total not greater than 14) then the flow of execution will skip past the code block. In other words, it will not execute the code in the curly braces.

Finally, the second if statement controls the message if the user loses. In the next unit, you'll use a variation on the if statement to shorten these two statements into a single statement that more clearly expresses the intent.

What is a Boolean expression?

A Boolean expression is any code that returns a Boolean value, either true or false. The simplest Boolean expressions are simply the values true and false. Alternatively, a Boolean expression could be the result of a method that returns the value true or false. For example, here's a simple code example using the string.Contains() method to evaluate whether one string contains another string.

string message = "The quick brown fox jumps over the lazy dog.";
bool result = message.Contains("dog");
Console.WriteLine(result);

if (message.Contains("fox")){
    Console.WriteLine("What does the fox say?");
}

Because the message.Contains("fox") returns a true or false value, it qualifies as a Boolean expression and can be used in an if statement.

Other simple Boolean expressions can be created by using operators to compare two values. Operators include:

  • ==, the "equals" operator, to test for equality
  • >, the "greater than" operator, to test that the value on the left is greater than the value on the right
  • <, the "less than" operator, to test that the value on the left is less than the value on the right
  • >=, the "greater than or equal to" operator
  • <=, the "less than or equal to" operator
  • and so on

Note
The C# training series on Microsoft Learn devotes an entire module to Boolean expressions. There are many operators you can use to construct a Boolean expression, and you'll only cover a few of the basics here in this module. For more on Boolean expressions, see the Microsoft Learn module titled "Evaluate Boolean expressions to make decisions in C#".

In this example, you evaluated the Boolean expression total > 14. However, you could have chosen the Boolean expression total >= 15 because in this cas e, they're the same. Given that the rules to the game specify "If the sum of the three dice, plus any bonuses, is 15 or greater, you win the game", you should probably implement the >= 15 expression. You'll make that change in the next step of the exercise.

What is a code block?

A code block is a collection of one or more lines of code that are defined by an opening and closing curly brace symbol { }. It represents a complete unit of code that has a single purpose in your software system. In this case, at runtime, all lines of code in the code block are executed if the Boolean expression is true. Conversely, if the Boolean expression is false, all lines of code in the code block are ignored.

You should also know that code blocks can contain other code blocks. In fact, it's common for one code block to be "nested" inside another code block in your applications. You'll begin nesting your own code blocks later in this module when you create one if statement inside the code block of another.

Note
The C# training series on Microsoft Learn devotes an entire module to understanding code blocks. Code blocks are central to understanding code organization and structure, and they define the boundaries of variable scope. See the module Control variable scope and logic using code blocks in C#.

Add another if statement to implement the doubles bonus

Next, you can implement the rule: "If any two dice you roll result in the same value, you get two bonus points for rolling doubles". Modify the code from the previous step to match the following code listing:

In the Visual Studio Code Editor, locate the cursor on the blank code line above the first if statement.

To create your "doubles" game feature, enter the following if statement.

if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3)){
    Console.WriteLine("You rolled doubles! +2 bonus to total!");
    total += 2;
}

Here you combine three Boolean expressions to create one composite Boolean expression in a single line of code. This is sometimes called a compound condition. You have one outer set of parentheses that combines three inner sets of parentheses separated by two pipe characters.

The double pipe characters || are the logical OR operator, which basically says "either the expression to my left OR the expression to my right must be true in order for the entire Boolean expression to be true". If both Boolean expressions are false, then the entire Boolean expression is false. You use two logical OR operators so that you can extend the evaluation to a third Boolean expression.

First, you evaluate (roll1 == roll2). If that's true, then the entire expression is true. If it's false, you evaluate (roll2 == roll3). If that's true, then the entire expression is true. If it's false, you evaluate (roll1 == roll3). If that's true, then the entire expression is true. If that is false, then the entire expression is false.

If the composite Boolean expression is true, then you execute the following code block. This time, there are two lines of code. The first line of code prints a message to the user. The second line of code increments the value of total by 2.

To improve the readability of your code, update the second if statement as follows:

if (total >= 15)

Notice that you're now using the >= operator in the expression that's used to evaluate a winning roll. The >= operator means "greater or equal to". As a result, you can compare total to a value of 15 rather than 14. With these changes, the expression that you use to evaluate a winning roll now resembles the expression that you evaluate for a losing roll. This should help to make your code easier to understand (more readable). Since you are dealing with integer values, your new expression (total >= 15) will function identically to what you wrote previously (total > 14).

Take a minute to review your code.

Your code should match the following:

Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;

Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3)){
    Console.WriteLine("You rolled doubles! +2 bonus to total!");
    total += 2;
}

if (total >= 15){
    Console.WriteLine("You win!");
}

if (total < 15){
    Console.WriteLine("Sorry, you lose.");
}

Notice the improved alignment between the expressions used to evaluate winning and losing rolls.

Add another if statement to implement the triples bonus

Next, you can implement the rule: "If all three dice you roll result in the same value, you get six bonus points for rolling triples." Modify the code from the previous steps to match the following code listing:

In the Visual Studio Code Editor, create a blank code line below the code block of your "doubles" if statement.

To create your "triples" game feature, enter the following if statement.

if ((roll1 == roll2) && (roll2 == roll3)) {
    Console.WriteLine("You rolled triples! +6 bonus to total!");
    total += 6;
}

Here you combine two Boolean expressions to create one composite Boolean expression in a single line of code. You have one outer set of parentheses that combines two inner sets of parentheses separated by two ampersand characters.

The double ampersand characters && are the logical AND operator, which basically says "only if both expressions are true, then the entire expression is true". In this case, if roll1 is equal to roll2, and roll2 is equal to roll3, then by deduction, roll1 must be equal to roll3, and the user rolled triples.

On the Visual Studio Code File menu, click Save.

Take a minute to review your code.

Ensure that your code matches the following:

Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;

Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3)){
    Console.WriteLine("You rolled doubles! +2 bonus to total!");
    total += 2;
}

if ((roll1 == roll2) && (roll2 == roll3)) {
    Console.WriteLine("You rolled triples! +6 bonus to total!");
    total += 6;
}

if (total >= 15){
    Console.WriteLine("You win!");
}

if (total < 15){
    Console.WriteLine("Sorry, you lose.");
}

You should see output that resembles one of the following results:

Dice roll: 3 + 6 + 1 = 10
Sorry, you lose.

Or, like this:

Dice roll: 1 + 4 + 4 = 9
You rolled doubles! +2 bonus to total!
Sorry, you lose.

Or, like this:

Dice roll: 5 + 6 + 4 = 15
You win!

Or, if you're lucky, you'll see this:

Dice roll: 6 + 6 + 6 = 18
You rolled doubles! +2 bonus to total!
You rolled triples! +6 bonus to total!
You win!

But wait, should you really reward the player with both the triple bonus and the double bonus? After all, a roll of triples implies that they also rolled doubles. Ideally, the bonuses shouldn't stack. There should be two separate bonus conditions. This is a bug in logic that will need to be corrected.

Problems in your logic and opportunities to improve the code

Although this is a good start, and you've learned a lot about the if statement, Boolean expressions, code blocks, logical OR and AND operators, and so on, there's much that can be improved. You'll do that in the next unit.

Recap

  • Use an if statement to branch your code logic. The if decision statement will execute code in its code block if its Boolean expression equates to true. Otherwise, the runtime will skip over the code block and continue to the next line of code after the code block.
  • A Boolean expression is any expression that returns a Boolean value.
  • Boolean operators will compare the two values on its left and right for equality, comparison, and more.
  • A code block is defined by curly braces { }. It collects lines of code that should be treated as a single unit.
  • The logical AND operator && aggregates two expressions so that both subexpressions must be true in order for the entire expression to be true.
  • The logical OR operator || aggregates two expressions so that if either subexpression is true, the entire expression is true.

Exercise

Create nested decision logic with if, else if, and else

In the previous unit, you used multiple if statements to implement the rules of a game. However, at the end of the unit, you noticed that more expressive if statements are needed to fix a subtle bug in your code.

In this exercise, you'll use if, else, and else if statements to improve the branching options in your code and fix a logic bug.

Use if and else statements instead of two separate if statements

Instead of performing two checks to display the "You win!" or "Sorry, you lose" message, you'll use the else keyword.

Ensure that your Program.cs code matches the following:

Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;

Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3)){
    Console.WriteLine("You rolled doubles! +2 bonus to total!");
    total += 2;
}

if ((roll1 == roll2) && (roll2 == roll3)) {
    Console.WriteLine("You rolled triples! +6 bonus to total!");
    total += 6;
}

if (total >= 15){
    Console.WriteLine("You win!");
}

if (total < 15){
    Console.WriteLine("Sorry, you lose.");
}

This is the code that you completed in the previous unit.

Take a minute to examine the two if statements at the end of the file:

if (total >= 15){
    Console.WriteLine("You win!");
}

if (total < 15){
    Console.WriteLine("Sorry, you lose.");
}

Notice that both if statements compare total with the same numeric value. This is the perfect opportunity to use an else statement.

Update the two if statements as follows:

if (total >= 15){
    Console.WriteLine("You win!");
} else {
    Console.WriteLine("Sorry, you lose.");
}

Here, if total >= 15 is false, then the code block following the else keyword will execute. Since the two outcomes are related opposites, this is a perfect scenario for the else keyword.

Your updated Program.cs file should contain the following code:

Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;

Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3)){
    Console.WriteLine("You rolled doubles!  +2 bonus to total!");
    total += 2;
}

if ((roll1 == roll2) && (roll2 == roll3)){
    Console.WriteLine("You rolled triples!  +6 bonus to total!");
    total += 6;
}

if (total >= 15){
    Console.WriteLine("You win!");
} else {
    Console.WriteLine("Sorry, you lose.");
}

Modify the code to remove the stacking bonus for doubles and triples using nesting

In the previous unit, you saw that a subtle logic bug was introduced into your application. You can fix that issue by nesting your if statements.

Nesting allows you to place code blocks inside of code blocks. In this case, you'll nest an if and else combination (the check for doubles) inside of another if statement (the check for triples) to prevent both bonuses from being awarded.

Modify your code to match the following code listing:

Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;

Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3)){
    if ((roll1 == roll2) && (roll2 == roll3)){
        Console.WriteLine("You rolled triples!  +6 bonus to total!");
        total += 6;
    } else {
        Console.WriteLine("You rolled doubles!  +2 bonus to total!");
        total += 2;
    }
}

if (total >= 15){
    Console.WriteLine("You win!");
} else {
    Console.WriteLine("Sorry, you lose.");
}

Take a minute to review the nested if statements.

The goal is to create an inner if-else construct where the two outcomes are related opposites, and then use the opposing outcomes (if/true and else /false) to award the bonus points for triples and doubles. To achieve this goal, you check for doubles in the outer if statement, and then for triples in the inner if statement. This pattern ensures that when the inner check for triples returns false, your else code block can award the points for doubles.

Coming up, you will "hard code" the results of your three rolls in order to test your code logic.

Create a blank code line above the line where total is declared and initialized.

To test for a roll of doubles, enter the following code:

roll1 = 6;
roll2 = 6;
roll3 = 5;

Hard coding the three roll variables enables you to test the code without having to run the application dozens of times.

When your code runs, you should see:

Dice roll: 6 + 6 + 5 = 17
You rolled doubles!  +2 bonus to total!
You win!

To test for a roll of triples, update your hard-coded roll variables as follows:

roll1 = 6;
roll2 = 6;
roll3 = 6;

When your code runs, you should see:

Dice roll: 6 + 6 + 6 = 18
You rolled triples!  +6 bonus to total!
You win!

Use if, else, and else if statements to give a prize instead of a win-lose message

To make the game more fun, you can change the game from "win-or-lose" to awarding fictitious prizes for each score. You can offer four prizes. However, the player should win only one prize:

  • If the player scores greater or equal to 16, they'll win a new car.
  • If the player scores greater or equal to 10, they'll win a new laptop.
  • If the player scores exactly 7, they'll win a trip.
  • Otherwise, the player wins a kitten.

Modify the code from the previous steps to the following code listing:

Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;

Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3)){
    if ((roll1 == roll2) && (roll2 == roll3)){
        Console.WriteLine("You rolled triples!  +6 bonus to total!");
        total += 6;
    } else {
        Console.WriteLine("You rolled doubles!  +2 bonus to total!");
        total += 2;
    }
    Console.WriteLine($"Your total including the bonus: {total}");
}

if (total >= 16){
    Console.WriteLine("You win a new car!");
} else if (total >= 10){
    Console.WriteLine("You win a new laptop!");
} else if (total == 7){
    Console.WriteLine("You win a trip for two!");
} else {
    Console.WriteLine("You win a kitten!");
}

Take a minute to review the updated if-elseif-else construct.

The if, else if, and else statements allow you to create multiple exclusive conditions as Boolean expressions. In other words, when you only want one outcome to happen, but you have several possible conditions and results, use as many else if statements as you want. If none of the if and else if statements apply, the final else code block will be executed. The else is optional, but it must come last if you choose to include it.

Use the technique of temporarily hard coding the roll variables to test each message.

Recap

  • The combination of if and else statements allows you to test for one condition, and then perform one of two outcomes. The code block for the if will be run when the Boolean expression is true, and the code block for the else will be run when the Boolean expression is false.
  • You can nest if statements to narrow down a possible condition. However, you should consider using the if, else if, and else statements instead.
  • Use else if statements to create multiple exclusive conditions.
  • An else is optional, but it must always come last when included.

Exercise

Complete a challenge activity to apply business rules

Code challenges will reinforce what you've learned and help you gain some confidence before proceeding.

Challenge: Improve renewal rate of subscriptions

You've been asked to add a feature to your company's software. The feature is intended to improve the renewal rate of subscriptions to the software. Your task is to display a renewal message when a user logs into the software system and is notified their subscription will soon end. You'll need to add a couple of decision statements to properly add branching logic to the application to satisfy the requirements.

Prepare your coding environment

To create the initial code for this challenge, enter the following code:

Random random = new Random();
int daysUntilExpiration = random.Next(12);
int discountPercentage = 0;

// Your code goes here

Notice that this code will generate a random number with a value of 0 - 11. The random number is assigned to an integer variable named daysUntilExpiration. You have another integer variable named discountPercentage that is initialized to 0.

Review the business rules for this challenge

  1. Rule 1: Your code should only display one message.

The message that your code displays will depend on the other five rules. For rules 2-6, the higher numbered rules take precedence over the lower numbered rules.

  1. Rule 2: If the user's subscription will expire in 10 days or less, display the message:
Your subscription will expire soon. Renew now!
  1. Rule 3: If the user's subscription will expire in five days or less, display the messages:
Your subscription expires in _ days.
Renew now and save 10%!

Note
Be sure to replace the _ character displayed in the message above with the value stored in the variable daysUntilExpiration when you construct your message output.

  1. Rule 4: If the user's subscription will expire in one day, display the messages:
Your subscription expires within a day!
Renew now and save 20%!
  1. Rule 5: If the user's subscription has expired, display the message:
Your subscription has expired.
  1. Rule 6: If the user's subscription doesn't expire in 10 days or less, display nothing.

Implement your solution code using if statements

Your solution must use separate if and if-else statements to implement the business rules. The if-else statement can include multiple else if parts.

  1. Create an if-else statement that displays a message about when the subscription will expire.

Tip
Use an else if to ensure each expiration rule is accounted for.

  1. Create a separate if statement that displays a discount offer.

The business rules indicate when a discount should be offered.