Making Decisions with If and Switch Statements

It's time for our code to make some decisions for itself and every programming language has some concept of conditional execution of code.

Download this lesson as a Polyglot Notebook to open in Visual Studio Code, or open directly in your web browser with Binder.

We can teach our code to execute code with conditional statements in C# with the keywords:

  • if
  • else
  • else if
  • switch or case

Conditional Statements

There are two statement-level conditional interactions in C#: if and switch...case statements. If statements can be combined with any number of else if statements and a single else statement to route code flow and interactions across branches of code. (Link to official docs)

We're going to write some code that you might have in a card game like Go Fish. Go Fish is a card game where you collect cards from other players by guessing what they have in their hand. When you guess correctly, you receive the other players cards that you requested.

We'll start with an if statement to guess if you have any 5s in your hand. You can re-run this code by clicking on the code and clicking the 'Play' button above or using the Ctrl+Enter hotkey

var myHand = "5♥️2♠️";
display("My hand: " + myHand);

// We can use the Contains method to test if a string contains a value:
display(myHand.Contains("5"));

// Another player is asking us if we have any 5's
display("Do you have any 5's?");
if ( myHand.Contains("5") ) {
    
    // Do this thing when seconds are even
    display("Give me your 5!");
    
}

The if statement starts with the if keyword and continues with a test in parenthesis. Next, the code to be executed if the test evaluates to true is contained within curly braces { }. The use of braces is optional, as long as the code to be executed is a single line.

var myHand = "5♥️2♠️";
display("My hand: " + myHand);

// Another player is asking us if we have any 5's
display("Do you have any 5's?");
if ( myHand.Contains("5") )
    display("Give me your 5!");

    display("This will always execute, even though it LOOKS LIKE its in the if statement");

This will always execute, even though it LOOKS LIKE its in the if statement. I recommend you always use braces because it makes it clearer what code is being conditionally executed

Great!, when the condition is met we can execute some code. What if we need some more complex branching and potentially apply secondary tests and code if those tests return false? We can start using the else and else if syntax to add these additional branches of code to be executed.

Let's look a more complex branching scenario:

var myHand = "5♥️2♠️7♠️K♦️Q♣️";
display("My hand: " + myHand);

display("Do you have any 6's?");
if (myHand.Contains("6")) {
    display("Give me your 6!");
} else if (myHand.Length > 14) {
    display("You have too many cards in hand!");
} else {
    display("Go fish!");
}

if (myHand.Contains("6"))      display("Give me your 6!");
else if (myHand.Length > 14)   display("You have too many cards in hand!");
else                           display("Go fish!");

Testing for one condition is fine... but what if we have a compound scenario where we need to test for multiple factors before we determine which branch to take?

You can chain together conditional tests using the logical OR | and the logical AND & operators.

var myHand = "5♥️2♠️7♠️K♦️Q♣️";
var cardsLeftInPool = true;
display("My hand: " + myHand);

display("Do you have any 6's?");
if (!myHand.Contains("6") & cardsLeftInPool) {
    display("Go Fish!  Draw a card from the pool");
    myHand = myHand + "2♣️";
} else if (myHand.Contains("6")) {
    display("Give me your 6");
} else {
    display("You don't have a 6 and there's no cards to draw");
}

There is another scenario that you will see many developers use to prioritize the compound boolean test inside an if statement, and that is using the 'short circuit' operators && and ||. They're referred to as a 'short circuit' operators because they evaluate the first condition on the left and if necessary evaluate the condition on the right side of the operator.

The && operator is called the Conditional Logical AND operator or referred to as AndAlso in Visual Basic. This operator behaves as follows:

  1. Evaluate the left-side of the operator
  2. IF the left-side evaluates to false, return false and stop processing
  3. ELSE return the result of evaluating the right-side of the operator

Let's look at an example where we'll check if I have a 6 in my hand. If I don't have a 6 and there are still cards in the pool, we'll draw a card.


var myHand = "5♥️2♠️7♠️K♦️Q♣️";
display("My hand: " + myHand);

bool CardsLeftInPool() {
    display("CardsLeftInPool was called");
    return true;
}

display("Do you have a 6?");
if (!myHand.Contains("6") && CardsLeftInPool()) {
    display("Go Fish!  Draw a card from the pool");
}

In this scenario, if we don't have a 6 in hand then the CardsLeftInPool method is executed. If we do have a 6 and there are cards left in the pool, then we are directed to 'Go Fish' and draw a card.

The || operator is called the Conditional Logical OR operator or referred to as the OrElse operator by the Visual Basic language. This operator behaves like the following:

  1. Evaluate the left-side of the operator
  2. IF the left-side evaluates to true, return true and stop processing
  3. ELSE return the result of evaluating the right-side of the operator

In this example, we'll check if we have any 6's.  If we have any sixes OR we can draw a card from the pool, we'll report that we got additional cards.

var myHand = "5♥️2♠️7♠️K♦️Q♣️";
var poolHasMoreCards = true;
display("My hand: " + myHand);

bool DrawCardFromPool() {
    display("DrawCardFromPool was called");
    return poolHasMoreCards;
}

display("Do you have any 6's?")
bool haveAnySixes = myHand.Contains("6");

var cardDrawn = "A♣️";
if (haveAnySixes || DrawCardFromPool()) {
    display("Got some cards!");
}

Conditional Operators

There are a number of operators that you can use to perform one-line interactions to conditionally assign values to variables or for using in other expressions. While these operators make your code shorter and sometimes easier to read, other times it can make for confusing statements when you chain together a number of these operators. As with any language feature or tool, a little bit goes a long way.

The Ternary Conditional Operator :

The Conditional Operator evaluates the term to the left of the ? and returns the value between the ? and : if the condition returns true. It returns the value to the right of the : if false. The following format makes this a little clearer:

is this true yes : no

Let's take a look at a sample:

var myHand = "5♥️2♠️7♠️K♦️Q♣️";
display("My hand: " + myHand);

// test if we have any 6's
display("Do you have any 6's?");
//                                      if true
//                                                                if false
var response = myHand.Contains("6")   "Yes, here is my 6"    : "Nope...  Go fish!";
display(response);

Switch Statements

Sometimes we have a LOT of conditions and branches that we want to evaluate and potentially traverse in our code. The switch statement allows you to configure using the switchcasebreak, and default statements the various branches you could potentially step down.

Use switch (test expression) to perform your test. Then use a series of case (result): statements to provide the various branching code paths to potentially execute. You can allow processing to 'fall out' of one statement into the next, and even provide a default branch at the end to ensure a branch is executed if none of the cases are matched.

Let's look at a real example that inspects the card we drew from the pool.  In the cases where the card is a 6 of diamonds, clubs, hearts, or spades let's celebrate!  Otherwise, we'll concede that its the opponent's turn.

var myHand = "5♥️2♠️7♠️K♦️Q♣️";

display("My hand: " + myHand);

display("Do you have any 6's?");
display("No, go fish");

var cardDrawn = "6♣️";
switch (cardDrawn) {
    case "6♦️":
        display("Yes!  I got a 6 of Diamonds");
        break;
    case "6♣️":
        display("It's a 6 of Clubs!");
        break;
    case "6♥️":
        display("W00t!  Its the 6 of Hearts!");
        break;
    case "6♠️":
        display("6 of Spades!  My lucky day");
        break;
    default:
        display("I didn't get a 6... your turn");
        break;
}

We can add additional tests for case statements using a when clause as well:

var myHand = "5♥️2♠️7♠️K♦️Q♣️";
display("My hand: " + myHand);

display("Do you have any 6's?");
display("No, go fish");

var cardDrawn = "6♣️";
switch (cardDrawn) {
    case "6♦️":
    case "6♣️":
    case "6♥️":
        display("I got a 6!");
        break;
    case "6♠️" when (myHand.Contains("6")):
        display("6 of Spades! That completes a pair");
        break;
    default:
        display("I didn't get a 6... your turn");
        break;
}

Switch Expressions

What if we want a similar conditional expression, but with the power of switch as a simple expression to interact with our variable types? Switch Expressions allow us to interact with those types. This means we can assign a value based on a shorter, more terse, expression

Starting with C# 8, available only with .NET Core 3+ and .NET Standard 2.1+, you can interact with these expressions.

Use the same switch keyword, with the value that you are evaluating and list each potential branch separated by commas ,.

var myHand = "5♥️2♠️7♠️K♦️Q♣️";
display("My hand: " + myHand);

display("Do you have any 6's?");
display("No, go fish");

var cardDrawn = "6♣️";

var message = cardDrawn[0] switch {
    '6'     => "I got a 6!",
    'A'     => "It's an Ace!",
    _       => "Nope.. didn't get the 6 I was looking for"
};

display(message);
About Us

CSharp In the Cards is a free technical educational series produced by Jeffrey T. Fritz and available in video, text, and source code formats. In the future, we plan to have more formats available

Contact Us

An unhandled error has occurred. Reload 🗙