ms_learn_csharp/014_scope_and_logic/014_csharp.md
2024-07-20 20:27:06 -04:00

12 KiB
Raw Blame History

Introduction

Selection and iteration statements use code blocks to group-together the code lines that should be executed, skipped, or iterated over. But that's not the only purpose for code blocks. Code blocks can also be used to control or limit variable accessibility. Variable "scope" refers to the portion of an application where a variable is accessible. Understanding how a code block affects variable scope is an important part of computer programming.

Suppose you're working on large application that uses nested iteration and selection statements to process array data. Your application uses variables to help accomplish common tasks throughout the application. Some variables serve the same purpose in different portions of the application, and you've made some attempt to reuse the variable names. As your application grows, you start seeing unexpected results for calculations, and errors that report a variable that is uninitialized or doesn't exist. You need to improve the approach you're using to declare and access variables, and you need to improve your understanding of variable scope.

In this module, you'll declare variables for use inside and outside the boundaries of code blocks. You'll remove code blocks in certain situations to make code more readable. You'll learn how code blocks affect the accessibility and visibility of your variables.

By the end of this module, you'll be able to use code blocks with more confidence, understanding how they impact the visibility and accessibility of your code.

Learning objectives

In this module, you will:

  • Understand the impact of declaring and initializing variables inside and outside of code blocks.
  • Improve the readability code blocks in if statements.

Prerequisites:

  • Experience declaring and initializing variables.
  • Experience with if-elseif-else selection statement structures.
  • Experience with foreach iteration statements.
  • Experience calling methods of classes in the .NET Class Library.

Exercise

Code blocks and variable scope

A code block is one or more C# statements that define an execution path. The statements outside of a code block affect when, if, and how often that block of code is executed at run time. The boundaries of a code block are typically defined by squiggly braces, {}.

In addition to their effect on execution path, code blocks can also affect the scope of your variables. The code samples that you examine during this exercise will help you understand the relationship between code blocks and variable scope.

Code blocks impact the scope of a variable declaration

Variable scope refers to a variable's visibility to the other code in your application. A locally scoped variable is only accessible inside of the code block in which it's defined. If you attempt to access the variable outside of the code block, you'll get a compiler error.

The remainder of this unit explores the relationship between code blocks and variable scope.

Prepare your coding environment

At the Terminal command prompt, to create a new console application in a specified folder, type dotnet new console -o ./path_to/TestProject and then press Enter.

You'll be using this C# console project to create, build, and run code samples during this module.

Create a variable inside of a code block

You will begin by looking at the case when a variable is initialized inside a code block.

Type the following code into the Visual Studio Code Editor:

bool flag = true;
if (flag) {
    int value = 10;
    Console.WriteLine($"Inside the code block: {value}");
}

The Program.cs file must be saved before building or running the code.

At the Terminal command prompt, to run your code, type dotnet run and then press Enter.

You should see the following output:

Inside the code block: 10

This is the expected output. But what if you want to access the variable value outside of the if statement code block?

Attempt to access a variable outside the code block in which it's declared

In the code editor, create a new code line below the if statement code block.

On the blank code line you created, add the following line of code:

Console.WriteLine($"Outside the code block: {value}");

Verify that your updated code looks like the following:

bool flag = true;
if (flag) {
    int value = 10;
    Console.WriteLine($"Inside the code block: {value}");
}
Console.WriteLine($"Outside the code block: {value}");

Save your code file, and then run your code.

Enter dotnet run from the Terminal command prompt to run your code.

Notice that when you attempt to run the application, you get a compilation error:

Program.cs(7,46): error CS0103: The name 'value' does not exist in the current context

The Program.cs(7,46) portion of the message tells you that the error is associated with line 7 in the Program.cs file, column 46.

This error is generated because a variable that's declared inside a code block is only accessible (can only be seen) within that code block. Since a variable cannot be accessed outside the code block in which it's declared, value cannot be accessed from line 7 of your code.

A variable that's declared in a method code block is referred to as a local variable. You may see the term local variable used when reviewing articles that discuss variable scope.

Move the variable declaration above the code block

To access a variable both inside and outside of a code block, you'll need to declare the variable prior to (above) the code block so that the code outside the code block can "see" the variable.

Update your code as follows:

bool flag = true;
int value;

if (flag){
    Console.WriteLine($"Inside the code block: {value}");
}

value = 10;
Console.WriteLine($"Outside the code block: {value}");

Take a minute to review the updates.

Notice that value is now declared (but not initialized) outside the if code block.

Save your updates, and then run your code.

Notice that you still get a compilation error.

This time, when you attempt to run the application, you get the following compilation error:

Program.cs(6,49): error CS0165: Use of unassigned local variable 'value'

The error is associated with line 6 inside the code block because value is uninitialized (has not been assigned a value). If the code line value = 10; was located above the if statement code block, the application would compile correctly and everything would be fine. However, since value hasn't been initialized, it cannot be accessed inside the code block.

Ensuring that your variables are initialized before attempting to access them will address this issue.

Initialize a variable as part of variable declaration

To initialize value as part of the variable declaration, update your code as follows:

bool flag = true;
int value = 0;

if (flag){
    Console.WriteLine($"Inside the code block: {value}");
}

value = 10;
Console.WriteLine($"Outside the code block: {value}");

This code addresses the "unassigned local variable" compilation error by initializing value as part of your variable declaration.

Save and run your code.

Notice that now, when you run the application, you see the following output:

Inside the code block: 0
Outside the code block: 10

Examine the compiler's interpretation of your code

To you avoid runtime errors, the C# compiler analyzes your code in the code editor* and during the build process. However, the compiler may not always interpret your code the same way that you do.

Consider the following two code samples that appear to serve the same purpose:

// Code sample 1
bool flag = true;
int value;

if (flag) {
    value = 10;
    Console.WriteLine($"Inside the code block: {value}");
}

Console.WriteLine($"Outside the code block: {value}");
// Code sample 2
int value;

if (true){
    value = 10;
    Console.WriteLine($"Inside the code block: {value}");
}

Console.WriteLine($"Outside the code block: {value}");

You may feel that these two samples should always produce the same result, but the C# compiler interprets these two code samples differently.

For the first code sample, the compiler interprets flag as a Boolean variable that could be assigned a value of either true or false. The compiler concludes that if flag is false, value will not be initialized when the second Console.WriteLine() is executed. Essentially the compiler considers the following two code execution paths to be possible:

// path when flag = true
int value;
value = 10;
Console.WriteLine($"Inside the code block: {value}");
Console.WriteLine($"Outside the code block: {value}");

AND

// path when flag = false
int value;
Console.WriteLine($"Outside the code block: {value}");

Since the compiler considers the second path a possibility (for code sample 1), it generates an error message during the build process. In addition, the code editor if available, warns you of this issue by displaying a red squiggly line under value (below the code block).

For the second code sample, the complier concludes that the contents of the if statement code block will always be executed (true is always true). The compiler doesn't generate a build error because it interprets the second code sample to have a single execution path as follows:

int value;
value = 10;
Console.WriteLine($"Inside the code block: {value}");
Console.WriteLine($"Outside the code block: {value}");

Recap

Here are a few important things to remember about code blocks:

  • When you declare a variable inside a code block, its visibility is local to that code block and that variable cannot be accessed outside of the code block.
  • To ensure that a variable is visible both inside and outside of a code bloc k, you must declare the variable prior to the code block (outside and above the code block).
  • Ensure that variables are initialized before your code attempts to access them (for all potential code execution paths).

Exercise

Complete a challenge activity using variable scope

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

Variable scope challenge

In this challenge, you'll use what you've learned about code blocks and variable scope to fix the poorly written code sample provided. There are many improvements that you can make. Good luck!

Code challenge: update problematic code in the code editor

Ensure that you have an empty Program.cs file open.

Type the following code into the editor:

int[] numbers = { 4, 8, 15, 16, 23, 42 };

foreach (int number in numbers) {
    int total;

    total += number;

    if (number == 42) {
       bool found = true;

    }
}

if (found) {
    Console.WriteLine("Set contains 42");
}

Console.WriteLine($"Total: {total}");

Review the intended output.

When you have completed the required code edits, your application should produce the following output:

Set contains 42
Total: 108

Complete the code updates required so that the existing Console.WriteLine() statements produce the desired output.

Variable scope may need to be adjusted.

Optimize your code for readability.

Depending on the amount of whitespace that you include and some other factors, you should have around 17 lines of code.

int[] numbers = { 4, 8, 15, 16, 23, 42 };
int total = 0;
bool found = false;

foreach (int number in numbers) {
    total += number;
    if (number == 42) {
       found = true;
    }
}

if (found) {
    Console.WriteLine("Set contains 42");
}

Console.WriteLine($"Total: {total}");