317 lines
9.9 KiB
Markdown
317 lines
9.9 KiB
Markdown
|
# 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:
|
|||
|
|
|||
|
```cs
|
|||
|
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:
|
|||
|
|
|||
|
```txt
|
|||
|
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:
|
|||
|
|
|||
|
```cs
|
|||
|
Console.WriteLine($"Outside the code block: {value}");
|
|||
|
```
|
|||
|
|
|||
|
Verify that your updated code looks like the following:
|
|||
|
|
|||
|
```cs
|
|||
|
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:
|
|||
|
|
|||
|
```txt
|
|||
|
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:
|
|||
|
|
|||
|
```cs
|
|||
|
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:
|
|||
|
|
|||
|
```txt
|
|||
|
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:
|
|||
|
|
|||
|

|
|||
|
```cs
|
|||
|
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:
|
|||
|
|
|||
|
```txt
|
|||
|
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:
|
|||
|
|
|||
|
```cs
|
|||
|
// 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}");
|
|||
|
```
|
|||
|
|
|||
|
```cs
|
|||
|
// 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:
|
|||
|
|
|||
|
```cs
|
|||
|
// path when flag = true
|
|||
|
int value;
|
|||
|
value = 10;
|
|||
|
Console.WriteLine($"Inside the code block: {value}");
|
|||
|
Console.WriteLine($"Outside the code block: {value}");
|
|||
|
```
|
|||
|
|
|||
|
AND
|
|||
|
|
|||
|
```cs
|
|||
|
// 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:
|
|||
|
|
|||
|

|
|||
|
```cs
|
|||
|
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).
|
|||
|
|
|||
|
---
|
|||
|
|
|||
|
##
|