Types, Variables and Casting
In C# every variable you declare must have a defined data type, a feature which makes C# a type safe language. This allows the compiler to check your code, before it is compiled, for some errors that will result in a program crash. We will have a look at this in more detail later in this tutorial.
Variables for the basic data types are declared by specifying the data type, followed by the variable name.
string myString;
decimal accountBalance;
These are three data types that are commonly used in most applications. There is a cheat sheet which shows all the Data Types and Ranges, which lists all the data types, the kind of data they support, the range of values they can hold and their default values.
Naming Variables
Variable names, like method names, have rules that govern how they should be named. Variables and methods must:
- start with a letter or underscore
- contain only letters, numbers and the underscore character
- not use reserved words or keywords
As well as those rules, there are some recommendations as well, for good practice and readability. Some of these are listed below:
Variable names should always be meaningful, but not too verbose. You should not use single letter identifiers except for loop control (where you should use i,j and k) or for mathematical equations (e.g. x = x * y^2).
You should always use the data type most appropriate for its use. For example, a variable to hold day of month would never rise above 31, so a byte would be a better data type over an int or decimal.
Assignment and Initialisation
Variables declared as above will be given default values, as described in the cheat sheet, but you may wish to initialise your variables to something more meaningful or appropriate. You can do this one of two ways.
When you declare the variable:
string myString = "Hello World";
decimal accountBalance = 34.87323;
or you can perform a regular variable assignment after the variable has been declared:
string myString;
decimal accountBalance;
myNumber = 12345;
myString = "Hello World";
decimal accountBalance 34.87323;
Because C# is a type safe language, you will not be able to assign a string to a variable.
You can also assign a variable the value of another variable of the same type.
int y;
y = x;
Variable assignment assigns the value of x to y. X will still retain its original value; Y is just given the value of X.
Types of type
In the .Net world, there are two different types that a data type can be. It can either be a reference type or a value type.
- Reference types are created on the heap, which is an area of memory where objects are created.
- Value types are created on the stack, which is a separate area of memory used to hold values.
The Stack and Heap are covered in more detail in the Introduction to .Net tutorials, and reference and value types are covered in depth in the Common Language Specifications topic.
Examples of Value types are int, float, struct, and enum.
Type Casting
Some data types can be assigned to a different type if they can be implicitly cast. This means that a small number can be assigned to a large number, but not vice versa.
Let's take two data types, the byte and the long. As you can see from the cheat sheet, a byte can hold whole numbers between 0 and 255 and a ulong can hold whole numbers between 0 and 9,223,372,036,854,775,807. Think of these as a shot glass and a pint glass.
ulong pintGlass;
In these analogies, please try an imagine that when we "pour" one glass into another glass, the original glass does not loose any of its contents. Rather, an equal amount of fluid is added to the other glass, while the original retains its contents.
Implicit Casting
It makes sense that you can pour the contents of the shot glass into the pint glass; there really is no danger of it overflowing, so the compiler will allow this to happen, without any warnings. This is called an implicit type cast and is done by the compiler automatically each time you assign a variable to another variable.
Explicit Casting
So what happens if you want to pour the contents of the pint glass into the shot glass? It may be possible, it depends on how much is in the pint glass. The compiler will see this as dangerous as there is a chance that the shot glass will overflow, so it will flag an error and prevent the program from compiling.
Cannot implicitly convert type 'ulong' to 'byte'. An explicit conversion exists (are you missing a cast?)
It is possible however to say to the compiler, "I know what I am doing, please let me pour the contents of my pint glass into my shot glass." This is called an explicit type cast, and is performed using the data type you are converting to in brackets just before the variable.
In this case the compiler assumes we know what we are doing and allows it.
If the shot glass does overflow, the value of the shotGlass will rollover and start from 0, so if you try and put a value of 256 into the shotGlass, the value would be 0, a value of 257 would be 1, 258 would be 2 and so on.
You should only explicitly type cast when you are certain that the values will fit, and it is sensible to test for this condition before performing the conversion.
Floating Point
Floating-point numbers are able to store values with a decimal fraction as well as a value, for example 2.5632. You can implicitly cast an int to a float or decimal type, but you cannot implicitly cast a decimal or float to an int as an int will not be able to hold the data after the decimal point. You can explicitly cast, however you will loose any decimal data, i.e. 2.5632 cast as an int will become just 2.
Review Questions
Can you spot the invalid variable names in these samples?
int 2counter;string $myString;char Initialclass this;int __hwnd
- Invalid. Names cannot begin with a number.
- Invalid. Names cannot start with a character other than letters or underscore.
- Valid.
- Invalid. this is a keyword.
- Valid.
Can you guess the result of these explicit casts?
float pi = 3.14159;
string myString = "Hello World";
decimal price = 9.95;
- int y = i;
- int y = (int) myString;
- int x = (int) pi;
- decimal x = (decimal) i;
- Implicit cast of int = int. Valid.
- Cannot explicitly convert string to int. Invalid.
- pi is explicitly converted to int, however loses decimal data. x = 3.
- i is explicitly converted to type decimal. Valid
Summary and Conclusion
We have briefly seen a few of the common data types and seen how to implicitly and explicitly cast variables. In the next tutorial we will have a look at the main method and how to create custom methods.
Introducing Methods and Main()
In the last tutorial we wrote a simple hello world program where we saw the Main method, but we didn't explain anything about what it is or what it does. The "Main" is a method that must exist in every program, as the compiler uses this to decide what to do when the program runs. This is called the entry point for the program.
In this tutorial we will look at the Main method and we will also see how to create a new method that we can run (call) from the Main. Let's have a look at our Hello World again.
class HelloWorld
{
static void Main()
{
Console.WriteLine("Hello World!");
}
}
Listing 1-1, Hello World program
As you can see on line 5, our Main method is declared using
Note: The M is capital and is case sensitive. The Main method must always be marked as static otherwise it cannot be run without creating an instance of the class. We will look at static and void in a later tutorial where we look at types and methods in more detail. In a nutshell they describe to the compiler where the method can be called from (static means can be called without an instance of the class) and what the method will return (void in this case means nothing is returned).
All methods are blocks of code, and a block of code is always encased within curly brackets (braces).
Methods are always executed from the top brace down to the bottom brace, in sequential order. When the compiler reaches the end of the Main method, the program exits.
Creating Methods
We can add another method to our project in much the same way as the Main method. After the closing brace of the Main method, we will add in another method called "myMethod". Also add in an empty code block with open and close braces.
The method name can be anything you like as long as it follows a few general rules:
Method names must:
- Be Unique
- Not the same as a keyword
- Contain only letters or numbers or the underscore character (_)
- not start with a number
There are also several guidelines that should be observed for good coding practice, but they do not affect the compiler, or the running of the program.
Going back to our old Hello World program, the code should look like this when you add our new method.
class HelloWorld
{
static void Main()
{
Console.WriteLine("Hello World!");
}
static void myMethod()
{
}
}
Listing 1-2, Adding a new Method
Now we need our method to do something, so add another line between the braces
Try and build your project now, using Ctrl+Shift+B and hopefully you will receive a successfully built message. Now running the project using the F5 key, or the play symbol on the toolbar.
Can't see the console window?
Depending on the configuration of your installation of Visual Studio, you may see a console window flash up and vanish very quickly. If this is the case we need to stop the program from exiting by adding another line into the Main method. After the Console.WriteLine line, add a new line
This will cause the program to wait for an input before exiting. Alternatively you can run the program without debugging (Ctrl+F5), which will cause the program to output a message "Press any key to continue…" and wait before exiting. The downside of this method is you cannot debug your program.
Run the program now, and you should see the console window with a line that says "Hello World!".
Why does it not show "myMethod Has Been Called" as well?
We have not called myMethod yet, so the code in myMethod does not get executed. Press the Enter key to close the program and return to the editor. We can fix our little problem by adding
between the Console.WriteLine and Console.ReadLine lines. This will call myMethod and cause the compiler to break out of Main and into myMethod. When it reaches the end of myMethod, it will return to the point in Main where it left off. This is explained in more detail in a later tutorial about Flow Control.
Now when you run the program, you will see two lines on the console window.
Completed Source Listing
class HelloWorld
{
static void Main()
{
Console.WriteLine("Hello World!");
myMethod();
Console.ReadLine();
}
static void myMethod()
{
Console.WriteLine("myMethod Called");
}
}
Listing 1-3, Full Code for Tutorial
Summary and Conclusion
In this tutorial we have seen the Main method and how it works, we covered code blocks using braces and creating a simple method as well as calling it from Main. We also touched on program flow control.
In the next tutorial we will have a closer look at methods, how to pass parameters and returning a result from a method.
Parameters and Return Values
We will see how to pass parameters to a method and how to return a value back, and cover more advanced features like variable length parameters, passing by reference and output parameters.In our Hello World program we saw the static void Main() method and we created another method the same way using static void myMethod()
What do we do if you want to pass some data to your new function and have it return a value back? How do you capture the result? And how do you pass a parameter? Let's have a look using the code from the last tutorial.
class HelloWorld
{
static void Main()
{
Console.WriteLine("Hello World!");
myMethod();
Console.ReadLine();
}
static void myMethod()
{
Console.WriteLine("myMethod Called");
}
}
Listing 1-1, Hello World calling a Mathod
Rename the myMethod function to something a bit more meaningful, like addNumbers. You will need to change both lines 8 (calling) and 12 (declaration).
The next thing we need to do is modify our new addNumbers method to accept parameters. We can do this by declaring two variables within the parenthesis. These are method parameters.
Next we need to perform an action on these numbers, so we will add them together and store them in another variable.
You can use parameters that have been passed into the method in exactly the same way as you would use a variable that has been declared.
Next we need to change are Console.WriteLine to output the calculated value:
You can see more about the curly braces and how strings are formatted in the Format Strings cheat sheet.
Your new source should look like this:
class HelloWorld
{
static void Main()
{
Console.WriteLine("Hello World!");
myMethod();
Console.ReadLine();
}
static void myMethod(int x, int y)
{
int z = x + y;
Console.WriteLine("Result of {0} + {1} = {2}", x, y, z);
}
}
Listing 1-2, passing Values to addNumbers Method
Now, try and Build the project. Your compiler will raise an error:
No overload for method 'addNumbers' takes '0' arguments
This is because we have not passed the correct number of parameters to our function. This is quite a common error, especially when a function takes many parameters.
If you go back up to line 8 where we call our addNumbers method, place the cursor within the brackets and press (Shift+Ctrl+Space) and the Intellisense will tell you the parameters that the method you are calling expects. It will also tell you which parameter you are currently on by highlighting it in bold. Parameters are separated using a comma, so add two numbers in now, and watch how Intellisense updates to help you.
Now your project should build and you will see the result of the calculation being displayed.
Returning a Value
Instead of outputting the calculation to the screen, you may wish to return it back to the calling method (the method where the addNumbers method was called from. In this case Main).
We need to make another change to the method. This time we need to change the word void (which means the method does not return a value) into int (which means the method returns a number).
Now we need to remove the Console.WriteLine line and replace it with:
And that's all we need to do to make our method return a value. We just need to change our calling function to pick up the result.
{
Console.WriteLine("Hello World!");
int result = addNumbers(2,2);
Console.WriteLine("Result of addNumbers = {0}", result);
Console.ReadLine();
}
A Few Notes
The value you use to hold the result of a function must be of the same type as the return type of the method you are calling.
The value you return through return myValue must be of the same type as the methods return type. This is because C# is a type safe language. That means the compiler will make sure that you are not trying to place a string in a variable that is declared as a number.
Other ways of passing data
There are three ways of passing data to and from a method. We have just seen the first way - by value, but there are two other ways.
By Reference
Variables passed in by value are read-only. Within the method you cannot assign a value to a parameter unless it is passed by reference. When you pass a parameter by reference, you pass the memory location rather than the data. The method can then access and modify the memory location.
You can specify that a parameter should be passed by reference using the refkeyword. Parameters passed in this manner are read/write, you can read the value and also write a new value which can be picked up by the calling method.
static void myMethod(ref int myInt)
To call a method with the ref keyword, you also need to specify ref in the parameter list.
myMethod(ref z);
Output Parameters
The third way is through the use of output parameters and the out keyword. This allows values to be passed out, but not in, thus it is a write-only parameter.
{
Console.WriteLine(myInt); // Will Error;
// Return a value
myInt = 10;
return true;
}
You can see that this method will allow you to return more than one value back to the calling method. You can have as many out parameters as you need.
To call a method with out parameters you need to specify out in the parameter list in the same way as you do with reference.
if (myMethod(a) == true)
{
Console.WriteLine(a);
}
Difference between reference and output parameters
One of the main differences between the two is that parameters passed by ref do not have to be assigned to, whereas output parameters must be assigned to before the method exits.
Variable Length Parameters
Sometimes it is required to pass n number of parameters to a method. A good example is a method to calculate the average of a series. You could pass in 1, 2, 3 or 10 values. Variable length parameter lists can be used instead of multiple int declarations. They are declared using the params keyword. Variable length parameters are always passed by value.
{
int total = 0;
foreach (int value in items)
total += value;
return (total / items.Length);
}
Console.WriteLine(average(1,2,3));
Console.WriteLine(average(1,2,3,4,5,6,7,8,9));
This technique can be used to pick up on arguments passed into the program in the Main method:
Summary and Conclusions
We have seen how to pass numbers to a method and perform a calculation on them, returning the value back to method it was called from. We used variables of type int in this example, but you can use any of the defined types, a class, array, struct or any other data type.
C# Operator List
C# has a large number of operators, some will be used in every single program or module, while others you may not ever use.
The most common of the operators are the arithmetic and logic operators. These will be very familiar to you is you know other programming languages, or mathematics.
Arithmetic
| Operator | Action | Example | Result |
|---|---|---|---|
| + | Addition | z = 1 + 2 | z = 3 |
| - | Subtraction | z = 1 - 2 | z = -1 |
| * | Multiplication | z = 2 * 2 | z = 4 |
| / | Division | z = 22 / 7 | z = 3.142857 |
| % | Modulus | z = 22 % 7 | z = 1 |
| The modulus operator (%) computes the remainder after dividing its first operand by its second. | |||
Logic
| Operator | Action | Example | Result |
|---|---|---|---|
| && | Logical AND | true && false true && true false && false | false true false |
| || | Logical OR | true || false true || true false || false | true true false |
| ! | Logical NOT | true && !false | true |
Increment and Decrement
| Operator | Action | Example | Result |
|---|---|---|---|
| ++ | Increment | a=1; a++; | a = 2 |
| – | Decrement | a=1; a–; | a = 0; |
Relational
| Operator | Action | Example | Result |
|---|---|---|---|
| == | Equals | x = 1; x == 1 | true |
| != | NOT Equals | x = 1; x != 1 | false |
| < | Less than | x = 1; x <> | true |
| > | Greater than | x = 1; x > 0; | true |
| <= | Less than or equal to | x = 1; x <= 0 | false |
| >= | Greater than or equal to | x = 1; x >= 5 | false |
Assignment
| Operator | Action | Example | Result |
|---|---|---|---|
| = | Assignment | x = 1 | |
| += | Incremental Addition | a=1; a += 3; | a = 4; |
| -= | Incremental Decrement | a=1; a -= 3; | a = -2; |
| *= | Multiply by | a=2; a *= 4; | a = 8; |
| /= | Divide by | a=8; a *= 2; | a = 4; |
| %= | Modulus or Remainder | a=8; a %= 3; | a = 2; |
| &= | Logical AND | "x &= y" is equivalent to "x = x & y" | |
| |= | Logical OR | "x |= y" is equivalent to "x = x | y" | |
| <<= | Left Shift | "x <<= y" is equivalent to "x = x <<> | |
| >>= | Right Shift | "x >>= y" is equivalent to "x = x >> y" |
others
| Operator | Action | Example | Result |
|---|---|---|---|
| & | Logical AND | if (false & ++i == 1) | false |
| | | Logical OR | true | false false | false | false true |
| ^ | Logical Exclusive XOR | false ^ false false ^ true true ^ true | false true false |
| ~ | Bitwise Complement | x = ~0×00000000 | x = 0xffffffff |
| << | Left Shift | 1 <<> | 2 |
| >> | Right Shift | -1000 >> 3 | -125 |
| ?? | Default Value | int y = x ?? -1; | if x = null y = -1 else y = x |
| | Conditional Operator | condition ? expression if true : expression if false |
Conditional Statements
Having just seen the C# Operators in the last tutorial, we will now look at using the logical operators in more depth and look at the conditional statements.
Conditional statements allow different sections of code, or actions, to be executed depending on a condition being met. Conditions can be used to validate user input, display certain data depending on date or day of week, or any one of thousands of conditions.
If… Else
The most commonly used conditional statement is the If… Else block, in which a statement is evaluated to true or false and depending on the result, a different section of code is executed.
In this sample the statement checks if the condition is true, if it is it executes the first block of code. If the condition is false then it executes the second.
Conditions in the if statement must ALWAYS evaluate to TRUE or FALSE.
if (x >= 3)
{
Console.WriteLine("X is greater than or equal to 3.");
}
else
{
Console.WriteLine("X is less than 3.");
}
Listing 1-1, Sample If… Else statement
Have a play by changing the value of X and seeing which code block is executed.
If you only have ONE statement to be executed, like our example, you can omit the braces, but if you have more than one statement you will need the braces. This can make the code a little easier to read, but some consider it bad form.
if (x >= 3)
Console.WriteLine("X is greater than or equal to 3.");
else
Console.WriteLine("X is less than 3.");
Listing 1-2, Condensed If… Else statement
You don't need to have an else statement. If all you want is to output something on Monday for example:
Console.WriteLine("Today is Monday");
Listing 1-3, If statement
This will write out Today is Monday only if dayOfWeek is Monday, otherwise the code is skipped over.
Nested If Statements
If you have multiple scenarios, you can nest if… else statements:
Console.WriteLine("Today is Monday");
else if (dayOfWeek = Tuesday)
Console.WriteLine("Today is Tuesday");
else if (dayOfWeek = Wednesday)
Console.WriteLine("Today is Wednesday");
else if (dayOfWeek = Thursday)
Console.WriteLine("Today is Thursday");
else if (dayOfWeek = Friday)
Console.WriteLine("Today is Friday");
Listing 1-4, Nested If… Else statement
But this can get a little complicated for many conditions so a much easier and efficient method would be to use a switch statement.
Switch Statement
In the previous example with the multiple daysOfWeek, by the time Friday is tested the program has executed four if statements which is a very inefficient method. The code is also a little difficult to read and understand, so a much better method would be to use a switch case statement.
The above example can be simplified to this:
{
case "Monday":
Console.WriteLine("Today is Monday");
break;
case "Tuesday":
Console.WriteLine("Today is Tuesday");
break;
case "Wednesday":
Console.WriteLine("Today is Wednesday");
break;
case "Thursday":
Console.WriteLine("Today is Thursday");
break;
case "Friday":
Console.WriteLine("Today is Friday");
break;
}
Listing 1-5, Switch statement
As you can see, this is much easier to read, and there is only one conditional statement that gets executed so the code is more efficient and faster to execute. Each section of code to execute ends with a break keyword. This tells the compiler that the case has ended. Unlike some languages, such as PHP, you cannot `fall through` case blocks if code exists. You can only fall through when one case directly follows another case statement:
Console.WriteLine("Today is a Weekend"); // This will ERROR!
case "Sunday":
Console.WriteLine("Today is a Weekend");
break;
Listing 1-6, Sample fall through case - Invalid
case "Sunday":
Console.WriteLine("Today is a Weekend"); // This is OK!
break;
Listing 1-7, Sample fall through case - Valid
Another useful part of the Switch…Case block is that of a default action. If none of the cases specified are met, then the default will be executed.
{
case "Monday":
Console.WriteLine("Today is Monday");
break;
case "Tuesday":
Console.WriteLine("Today is Tuesday");
break;
case "Wednesday":
Console.WriteLine("Today is Wednesday");
break;
case "Thursday":
Console.WriteLine("Today is Thursday");
break;
case "Friday":
Console.WriteLine("Today is Friday");
break;
default:
Console.WriteLine("Today is a Weekend!!!");
break;
}
Listing 1-7, Switch statement with default
Default must always be the last statement.
C# allows the use of other keywords as well as break to control the flow of the Switch statement. You can use goto, return and throw.
Goto
The use of Goto does not fall within the structured programming methodology and should be avoided at all costs.
Return
Used to return a value back to the calling function.
Throw
Throw is used to raise an exception, which will be captured by your Try… Catch block. This will be covered in much more detail in the section about Exception Handling.
Summary and Conclusions
We have seen how to use conditional statements to perform different actions based on whether the condition evaluates to true or false. We also saw how a switch statement can be used where there are multiple if else statements to improve readability and performance.
In the next tutorial we will look at how to iterate, or loop, in order to repeat a task many times.
Looping and Iteration
It is often necessary to repeat a task many times. This is a process known as iteration, or looping. C# has a number of methods for looping: Do, While, For and Foreach.
The type of iterative loop is governed by how it should perform and what data types are involved. Some loops check the exit condition before they exit the loop, while others guarantees at least one pass.
The While Loop
The simplest loop is the while loop. This is a loop that executes a code block while the condition is true.
while (i<10)
{
Console.WriteLine("Loop {0}",i);
i++;
}
Listing 1-1, A simple while loop
There is a danger however that you will get caught in an infinite loop. This is a loop where the exit condition is never met. An example of an infinite loop would be if you forgot the i++; line. i will always be less than 10, so the loop will never exit.
A while loop will check the condition before entering the loop, and if the condition is met first time there will be no loop.
The Do… While Loop
The do while loop is similar to the while loop, except that it does not check the condition until the end of the first iteration. You are guaranteed to have a minimum of one iteration every time.
do
{
Console.WriteLine("Loop {0}",i);
i++;
}while (i<10);
Listing 1-2, A simple do… while loop
Again, you must increment the loop counter yourself to avoid being caught in an infinite loop.
The For Loop
The for loop is one of the most common type of loop. It will loop from a starting count to a ending count then stop. For example you can loop through numbers 1 to 10. The basic format for a for statement is:
{
// Code to repeat
}
Listing 1-3, A simple for loop
Looping from 1 to 10 as our first example will be coded as follows:
{
// Code to repeat
}
Listing 1-4, A simple for loop
It looks a bit complicated, so we'll go through each aspect in turn.
int i=1: Declares a variable called i and initiates the value to 1. This is the loop starting value.
i<=10: The program will loop as long as i <= 10. Once this condition is no longer met (i.e. i > 10) the loop will exit.
i++: Increment the value of i by 1 for the next iteration.
You cannot change the value of i within the code to repeat, but you can access its value:
{
i = 67; // This line will ERROR!
Console.WriteLine("Loop: {0}", i);
}
Listing 1-4, Using for counters
Once the erroring line is removed, the program will output:
Loop: 1
Loop: 2
Loop: 3
Loop: 4
Loop: 5
Loop: 6
Loop: 7
Loop: 8
Loop: 9
Loop: 10
The ending condition does not have to be a fixed value, you can use a function that returns an int. For example, you can loop through all the values in an array (these will be in detail covered later) using the count function to return the number of elements in the array. You can then use the value of i to access the array element.
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday"
};
for (int i=0; i<=daysOfWeek.Length; i++)
{
Console.WriteLine("Day of Week: {0}", daysOfWeek[i]);
}
Listing 1-5, Using for loop on arrays
Will output:
Day of Week: Monday
Day of Week: Tuesday
Day of Week: Wednesday
Day of Week: Thursday
Day of Week: Friday
Foreach
The for statement has many individual statements that implement the loop mechanism to iterate through the items of an array. It isn't particularly intuitive and it is prone to error. A foreach statement is a better method for looping through elements of an array.
To iterate through the daysOfWeek array from the previous code, the for loop can be replaced with a foreach:
{
Console.WriteLine("Day: {0}", Day);
}
Listing 1-6, Foreach loop
It is much easier to understand what is happening in this example. We declare a value Day of type string (must be the same as the array data type) and it automatically gets assigned the value of daysOfWeek. On the next iteration we get the next array item, and so on until the end of the array is reached.
You cannot assign to the value of Day in this example as it is read only.
Summary and Conclusions
We have seen the four iterative loops, while, do while, for and foreach, and we have seen how they can be used to repeat an action many times on certain types of data.
In the next tutorial we will look at how the compiler flows through the code from start to finish. We will also have a look at flow control.
Flow Control and Entry Points
In C# applications, code is executed in a specific sequence. Execution of code starts at the program entry point, usually the Main method. From there it executes code sequentially until it gets to the end of the entry point, then the application closes.
The various code blocks affect the flow of execution; you can jump out to a method or skip over sections. The easiest way to see how a program flows is by using the . We won't be doing any debugging, but we will use the step into tool to have a look at how the compiler executes the code.
Start a new console project and copy in the following code:
{
static void Main()
{
Console.WriteLine("This is the first instruction executed.");
for (int i = 0; i < 5; i++)
{
Console.WriteLine("In a loop…");
//We will do this five times
}
int result = myMethod();
if (result == 1)
Console.WriteLine("myMethod returned 1");
else if (result == 2)
Console.WriteLine("myMethod returned 2");
else if (result == 3)
Console.WriteLine("myMethod returned 3");
else
Console.WriteLine("myMethod returned something else");
switch (result)
{
case 1: Console.WriteLine("myMethod returned 1"); break;
case 2: Console.WriteLine("myMethod returned 2"); break;
case 3: Console.WriteLine("myMethod returned 3"); break;
default: Console.WriteLine("myMethod returned something else"); break;
}
}
public static int myMethod()
{
return 3;
}
}
Once the code is in the editor, press F11 to start the debug step into tool. The console window will flash up, and then return to the editor. You will see that the first brace of the Main() method is highlighted in yellow. Press F11 again and it will jump down to the Console.WriteLine line. This is the line that is just about to be executed. Keep pressing F11 and you will see how the program executes the code. When it gets to the for loop, notice how it checks the conditions in the brackets. First it initialises the variable and then checks the exit condition before going into the loop for the first time. Press the F11 key a few more times and you will see that the value of i gets incremented, then it checks the exit condition again.
After a couple more iterations, the flow will jump down to the line that calls myMethod and then we see the flow jump again to the first brace of the myMethod statement, which returns 2. We then jump back up to the myMethod calling line and carry on from where we left off.
Next we have some nested if statements. In the previous tutorial about conditional statements we said that the nested if statement were inefficient. Now we will see the visual proof and compare that to the switch… case statement.
Step through the if statements with the F11 key and see how each one is executed in turn until we find one that is true. Keep on pressing the F11 key and compare the if statements with the switch statement. Notice how only one statement gets looked at and how many times less you press the F11 key.
After the switch statement the flow falls down to the last brace of the main function and then the program will end.
Entry Points
Every .Net assembly must have an entry point called Main(). This is the method that will be called when the assembly is loaded and is the controlling routine. When the entry point method has finished executing, the program will exit.
An assembly can have more than one Main() method, but only one Main can exist in a single class.
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main Called");
}
}
class Program2
{
static void Main()
{
Console.WriteLine("Main2 Called");
}
}
}
To specify which Main should run you need to use the /main compiler option, either on csc.exe or within the IDE. To configure the IDE to compile multiple entry points you need to:
- Select the project in Solution Explorer and bring up its properties.
- Click on the Application tab.
- Make sure that the Enable application framework check box is disabled.
- Change the value in the start-up object box to include
/main:Program2where program2 is the class containing the entry point to be used.
Unless you specify which entry point to use, the code will not compile.
Summary and Conclusions
In this tutorial we saw how flow of execution jumps around the code, but follows a set pattern. We also saw that the switch statement is more efficient than multiple nested if statements.
Stepping into code using F11 is one of the most important features of the C# debugger and allows the programmer to analyse each line before it is executed. This is very useful for finding the cause of errors.
No comments:
Post a Comment