6 Ways Of Decision Making In C#

by Kenji Elzerman
6 Ways Of Decision Making In C# - Kens Learning Curve

Decision making in C# is something you will do a lot. It determines the flow of the application you are making. You can make decisions in C# using user input, calculation, or data from a data source. Either way, you will need to know which decision making in C# you need to use. In this article, I will show you 6 ways of decision making in C#. It does not mean you can use them all. They all have pros and cons.

This article does not go into much depth about each decision making in C#. I show you the basic idea.

Prefer to see the video?

Video of decision making in C#. For those who rather watch a video than read an article.

Traditional If statement

I call this one traditional because it’s the most common decision making in C# and other languages. And it’s a pretty easy one to use. In most languages, the syntax is the same: You have two values you want to check with an operator and when both values are true you do some action.

A very basic if statement looks like this.

int a = 1;

if(a == 1)
{
    Console.WriteLine("A is 1!");
}

You always start with if, followed by a condition or conditional expression which will result in a true or false. When the condition is true, the code between the curly braces is executed. When the condition is not true (false), the application continues without the execution of the code between the curly braces.

This example is just checking on condition; a equals 1. But when you want to check more conditions that are related to or are important to the outcome, you need to add an else.
Else means, as it is in the name, if the first condition is false execute this. It looks like this:

int a = 1;

if(a == 1)
{
    Console.WriteLine("A is 1!");
}
else
{
    Console.WriteLine("Don't know how to handle this... Try again.");
}

This code shows that when a is not 1, the code inside the else will be executed.

But what if you have more conditions? Like a could also be 2 or do you want to make sure a is always higher than 0? You can add an else-if.
And else-if is basically a combination of the first if and an else. It also needs a condition. The else-if is located between the initial if and the else.

int a = -2;

if (a == 1)
{
    Console.WriteLine("A is 1!");
}
else if (a == 2)
{
    Console.WriteLine("A is not 1, but 2.");
}
else if (a <= 0)
{
    Console.WriteLine("A needs to be more than 0.");
}
else
{
    Console.WriteLine("Don't know how to handle this... Try again.");
}

It is also possible to combine two checks in the condition. For example; you want to make sure a is between 5 and 10:

int a = 6;

if (a == 1)
{
    Console.WriteLine("A is 1!");
}
else if (a == 2)
{
    Console.WriteLine("A is not 1, but 2.");
}
else if (a <= 0)
{
    Console.WriteLine("A needs to be more than 0.");
}
else if (a > 5 && a < 10)
{
    Console.WriteLine("A is between 5 and 10.");
}
else
{
    Console.WriteLine("Don't know how to handle this... Try again.");
}

The && operator means “and”, so a needs to be between 5 and 10. The || operator, which is called the “or” operator, means that a is higher than 5 or lower than 10.

The if statement is one of the most common decision making in C# and you will see it a lot. But as you may have noticed, the size of the complete if statement of the last example is rather big. Sure, you can remove the curly brackets, but developers prefer that. And that’s one of the biggest disadvantages of the if statement: if you are not careful it can become really big.

Switch

Another well-known decision making in C# is the switch. The result is the same as the if statement, but the switch works with cases. Each case represents a value of the condition you want to evaluate.
The basic switch structure is the keyword switch, a condition, and the cases. It looks like this:

int a = 1;

switch (a)
{
    case 1:
        Console.WriteLine("A is 1!");
        break;
}

I want to evaluate the value of a; the first case is the value 1. As soon as a equals 1, the code of case 1 is executed. Do notice the break. Now, in older versions, if you remove the break; the application will fall through the case into the next one. So the following code would show both Console.WriteLines:

int a = 1;

switch (a)
{
    case 1:
        Console.WriteLine("A is 1!");
    case > 0:
        Console.WriteLine("A is larger than 0!");
        break;
}

But in the newer versions, this isn’t possible anymore. Case 1 would give an error and you need to add the break again. But both cases don’t make sense; both are true. Which one is going to be executed? The first one. Let’s remove the case > 0.

If I want to rebuild the previous if statement to a switch, it would look like this:

int a = 11;

switch (a)
{
    case 1:
        Console.WriteLine("A is 1!");
        break;
    case 2:
        Console.WriteLine("A is not 1, but 2.");
        break;
    case <= 0:
        Console.WriteLine("A needs to be more than 0.");
        break;
    case > 5 and < 10:
        Console.WriteLine("A is between 5 and 10.");
        break;
    default:
        Console.WriteLine("Don't know how to handle this... Try again.");
        break;
}

I think most look familiar. Do notice the case > 5 and < 10. The and is the equivalent of &&. The equivalent of || (or) is or. Another thing to mention is the last case, the default. This is the else equivalent in an if statement.

A switch statement is the second most used decision making in C#. It’s a pretty simple syntax to check values and act on them. But, like an if statement, switch statements are known to grow rapidly. They are also not easy to control if you want to check multiple values, like the > 5 and <10.
I would also not use a switch statement if there are a lot of cases. Keep a switch short and clean.

Switch Expression (C# 8.0 and higher)

The Switch Expression is another decision making in C# and it looks a lot like the traditional switch but with a big difference. This switch uses expressions rather than cases. When you look closely you can recognize the traditional switch.

int a = 3;

Console.WriteLine(a switch
{
    1 => "A is 1!",
    2 => "A is not 1, but 2.",
    <= 0 => "A needs to be more than 0.",
    > 5 and < 10 => "A is between 5 and 10.",
    _ => "Don't know how to handle this... Try again."
});

The big difference between the traditional switch and the switch expression is the way it handles the result. A switch executes an action where the switch expression produces a value. Look closely at the code of the switch expression; each case, or pattern in this….case, is now an expression and each expression has a left hand (the value of the variable a) and a right hand. The right hand is the value that is being returned.

The syntax of the patterns remains the same as the cases, except for the default, which is now an underscore and it is called the discard pattern or simply a discard. It acts as a catch-all case or default case when none of the other patterns match.

Ternary Operator

A ternary operator is more a short-hand for an if statement and the basic syntax is this:

condition ? trueResult : falseResult;

You can apply the same syntax to do decision making in C#.

int a = 3;

Console.WriteLine(a == 1 ? "A is 1!" :
                a == 2 ? "A is not 1, but 2." :
                a <= 0 ? "A needs to be more than 0." :
                a > 5 && a < 10 ? "A is between 5 and 10." :
                "A is not 1. Try again.");

I don’t like this one a lot; it’s a lot of operators and it makes it less readable. Still, I do want you to know this one.

So, basically… Each condition is tested and when it’s not true it moves to the next condition. If none of the conditions are met, the last line is executed.
And just like with the switch expression, the ternary operator returns a value when a condition is met. It does not execute a method.

I wouldn’t use this one. It’s ugly and, when not careful, very hard to read. But that’s just my opinion.

Dictionary

Yes, you can use a dictionary to make decisions. The dictionary holds the conditions and the outcome. Again, this way of decision making in C# returns a value and does not execute code.

int a = 6;

var conditions = new Dictionary<Func<int, bool>, string>
{
    { x => x == 1, "A is 1!" },
    { x => x == 2, "A is not 1, but 2." },
    { x => x <= 0, "A needs to be more than 0." },
    { x => x > 5 && x < 10, "A is between 5 and 10." }
};

Console.WriteLine(conditions.FirstOrDefault(c => c.Key(a)).Value ?? "A is not 1. Try again.");

Each scenario is inside the dictionary, together with the outcome. Then, the code uses the FirstOrDefault on the key, which is the condition. When a key/condition is met, the value is returned and printed.

I’ll just copy-paste my opinion of the ternary operator here because I think the same about the use of the dictionary: I wouldn’t use this one. It’s ugly and, when not careful, very hard to read. But that’s just my opinion.

Strategy Pattern

The final decision making in C# I want to show you is the strategy pattern. This pattern data is based on an interface with different implementations. You have a bunch of classes implemented by one interface. One of the methods is to check a condition and return true or false. When it’s true it indicates you can use that implementation to execute the other method.

I would not use this pattern for simple decision making in C#, like the if statement or the switch. The strategy pattern is more for really complex decisions. For example when the outcome of a condition has a lot of lines of code or does complex stuff.

This is the idea:

public class Context
{
    private readonly IEnumerable<IMovieStrategy> movieStrategies;
    public Context(IEnumerable<IMovieStrategy> movieStrategies)
    {
        this.movieStrategies=movieStrategies;
    }
    public void ShowMovie(string title)
    {
        IMovieStrategy movie = movieStrategies.SingleOrDefault(x => x.Title == title) 
            ?? throw new Exception("Movie not found");
        Console.WriteLine(movie.Title);
        Console.WriteLine(movie.Description);
        Console.WriteLine($"{movie.ReleaseDate} ({movie.Age()} years old)");
    }
}

This is taken from a dedicated article for this pattern. This is not really for beginners and if you have no idea what I am talking about, please read the article of follow my C# boot camp.

This piece of code injects a list of classes that are implementing the IMovieStrategy interface. The method ShowMovie is getting one of those classes where the title parameter equals the title of the class. The Title is a property of the interface.
When one is found, the found class can be used to do some complex stuff.

Conclusion On Decision Making In C#

And here are 6 ways of decision making in C#. The if statement and the switch are the most used and easiest to understand. Perfect if you have small checks to make. But be careful not to get them too large. The bigger they get, the harder it is to understand them.

While the ternary operator and the dictionary could work, they are bulky, hard(er) to read, and could, just like an if statement and switch, grow too fast. I rarely use this one.

The strategy pattern requires a bit more work to create, but if you have complex code inside an if statements or switches, you are better off with this pattern. Don’t use it if you just want to check if a equals 1.

In the end, it all depends on what your requirements are. But keep a cool head, don’t overthink or overuse. KISS… Keep it simple, stupid.

About

Kens Learning Curve is all about learning C# and all that comes along with it. From short, practical tutorials to learning from A to Z.

 

All subjects are tried and used by myself and I don’t use ChatGPT to write the texts.

Contact

Use the contact form to contact me or send me an e-mail.

The contact form can be found here.

Email: info@kenslearningcurve.com

@2023 – All Right Reserved. Designed and Developed by Kens Learning Curve

Table Of Contents
Kens Learning Curve