Learn C# , CSharp Basic, CSharp Advance Programming

What is C#?

C# (pronounced "see sharp") is a modern, general-purpose, object-oriented programming language developed by Microsoft within the .NET initiative. C# has been approved as a standard by Ecma (ECMA-334) and ISO (ISO/IEC 23270).
C# is a strongly typed language meaning that every variable must be declared with a data type, and initialised prior to use. Once a variable has been defined, it cannot be redefined within it's scope. For example if you define a variable to hold a number, you cannot make it hold text later on. We will cover variables and data types shortly.
C# is an extension of C++ and while it retails a similar syntax and layout, it is also vastly different. C# takes the best parts of several programming languages and merges them together. It also adds a host of new features to make C# one of the most powerful languages around at the moment.
C# is a managed language which means that it is not compiled directly into machine code, but rather into an intermediate language which is executed within the common language runtime. We'll see more about this later.

 

What this means for new programmers

C# is easier to learn and work with for somebody new to programming. The language, Visual Studio and the .Net platform make it more difficult to make critical errors such as memory leaks and null references. C# syntax is much easier to understand than similar C++ which means that non-programmers can pick it up easier.

What this means for existing programmers

If you are migrating from Delphi/Pascal you will see some obvious similarity between the languages and it should be fairly similar from the start. It was for me. If you are migrating from C++ or Java, again it should be familiar. This is because C# is based on C++, Java and Delphi.
One of the most important concepts to understand is that there are no global variables or functions in C#. All methods and members must be declared within classes, however you can use static members of public classes can substitute for global variables and functions.
In the next tutorial in this series we will look at the nitty gritty of C# and start doing some programming work.


Your First Console Application

In this short tutorial, we will create a simple C# Console Application to verify that our version of Visual Studio has been installed correctly and that the .Net Framework is working properly. We will create the infamous "Hello World" application while demonstrating some important concepts of C# programming.
Having just installed Visual Studio, we should just test that the installation is working ok. To do this we will create a "Hello World" console application. We will introduce a few constructs that may be unfamiliar, but don't worry, we will cover these in greater detail in the upcoming tutorials.
For now, open up the Visual C# and create a new Console Application. This can be done from the File menu and selecting New
In order to keep things as simple as possible for the first lesson, select all the code (Ctrl+A) or Edit » Select All, and delete it. Next, you need to type in, or copy and paste the following code into the editor.
using System;
 
class HelloWorld
{
  static void Main()
  {
    Console.WriteLine("Hello World!");
  }
}
You should now run the program by pressing (Ctrl+F5) which will start without debugging, or from the menu select Debug » Build Without Debugging. I'll explain why in the next tutorial, but now you should see the console window that says "Hello World!"

Let's Examine the Code

On the first line, we are telling the compiler that we want to use something called System. System is a namespace that is provided by Microsoft. Namespaces are an important concept in C# (and the .Net Framework in general) and will be covered in a future tutorial. It is similar to include statements in languages such as C/C++ and PHP.
The next line of code is creating a class called HelloWorld. Again, a class is a fundamental concept in object orientated programming and will be covered in great detail in future tutorials. For now, think of a class as a container. Everything must be contained within a class in C#, unlike C/C++ and PHP where you can have variables inside or outside a class or function.
The next line of code defines the Main function for the program. We don't need to worry too much about Main at this stage, as we will cover it in a later session. Finally, our last line of code simply tells the program to write a line onto the screen. Console.WriteLine will write a line of text to the console screen and automatically add a new line, carriage return to the end. Notice there is a semi-colon at the end of the line. C#, like a lot of programming languages, uses the semi-colon to separate lines of code or operations. Every statement will have a semi-colon at the end.

Summary and Conclusion

Now you have built your first C# program using Visual C# Express, and we have introduced the basics of C# programming as well as some important concepts. In the next tutorial we will look at some of the data types you can use in C#, creating and using variables and introduce type casting.

 

Types, Variables and Casting

In this tutorial we will have a look at the data types in C# and the declaration of variables.
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.
int myNumber;
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.
There are more guidelines in our guide on Variable, Object and Control Naming.

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:
int myNumber = 12345;
string myString = "Hello World";
decimal accountBalance = 34.87323;
or you can perform a regular variable assignment after the variable has been declared:
int myNumber;
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.
int myNumber = "Hello World"; //This will not compile
You can also assign a variable the value of another variable of the same type.
int x = 5;
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 tutorial.
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.
byte shotGlass;
 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.
pintGlass = shotGlass;

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.
shotGlass = pintGlass;
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.
shotGlass = (byte) pintGlass;
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?

  1. int 2counter;
  2. string $myString;
  3. char Initial
  4. class this;
  5. int __hwnd
  1. Invalid. Names cannot begin with a number.
  2. Invalid. Names cannot start with a characters other than letters or underscore.
  3. Valid.
  4. Invalid. this is a keyword.
  5. Valid.

Can you guess the result of these explicit casts?

int i = 10;
float pi = 3.14159;
string myString = "Hello World";
decimal price = 9.95;
  1. int y = i;
  2. int y = (int) myString;
  3. int x = (int) pi;
  4. decimal x = (decimal) i;
  1. Implicit cast of int = int. Valid.
  2. Cannot explicitly convert string to int. Invalid.
  3. pi is explicitly converted to int, however loses decimal data. x = 3.
  4. 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()

This tutorial will introduce methods, where we will code a simple method and call it from another method. We will also look at the Main method of a C# application.
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.
using System;
 
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
static void Main()
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:
  1. Be Unique
  2. Not the same as a keyword
  3. Contain only letters or numbers or the underscore character (_)
  4. 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.
using System;
 
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
Console.WriteLine("myMethod Has Been Called");
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
Console.ReadLine();
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!".
Hello World Output

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
myMethod()
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.
Hello World Output

Completed Source Listing

using System;
 
class HelloWorld
{
    static void Main()
    {
        Console.WriteLine("Hello World!");
        myMethod();
        Console.ReadLine();
    }
 
    static void myMethod()
    {
        Console.WriteLine("myMethod Called");
    }
}

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

In this tutorial we will look at some more advanced features of methods. 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 the previous tutorial we created a Hello World program and 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 a simple program to add numbers.
Starting off with a new console project, we are going to create a method called addNumbers which will take two integers as parameters. This is done by defining a variable within the brackets of the method. Parameters are separated by a comma.
static void addNumbers(int x, int y)
This will tell the compiler that the addNumbers will need to have two integers, x and y. This method can only be called with the correct number of parameters, and they must be of the right type.
addNumbers(); // Will not work as there are no parameters
addNumbers(5); // Will not work as the method requires two parameters
addNumbers("1", "2"); // Will not work as these are strings
addNumbers(5, 5); // Will work 
 

Full code listing

using System;
 
class AddNumbersProgram
{
    static void Main()
    {
        addNumbers(5, 5);
    }
 
    static void addNumbers(int x, int y)
    {
        int z = x + y;
        Console.WriteLine("Result of {0} + {1} = {2}", x, y, z);
    }
}
When run this program should show
Result of 5 + 5 = 10

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 a few changes to the method. 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).
static int addNumbers(int x, int y)
Now we need to remove the Console.WriteLine line and replace it with:
return z;
Finally we need to capture the return result within Main.
int result = addNumbers(5, 5);
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.
using System;
 
class AddNumbersProgram
{
    static void Main()
    {
        int result = addNumbers(5, 5);
        Console.WriteLine("Result of addNumbers = {0}", result);
    }
 
    static int addNumbers(int x, int y)
    {
        int z = x + y;
        return z;
    }
}

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 ref keyword. 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.
int z = 2;
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.
static bool myMethod(out int myInt)
{
  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.
using System;
 
class OutputParameterDemo
{
    static void Main()
    {
        int a;
 
        if (myMethod(out a) == true)
        {
            Console.WriteLine(a);
        }
    }
 
    static bool myMethod(out int myInt)
    {
        // Set myInt to a value
        myInt = 10;
 
        // Return success
        return true;
    }
}
 

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.
static float average(params int[] items)
{
  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:
static void Main(string[] args)

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
ActionExampleResult
+ Additionz = 1 + 2z = 3
-Subtractionz = 1 – 2z = -1
*Multiplicationz = 2 * 2z = 4
/Divisionz = 22 / 7z = 3.142857
%Modulusz = 22 % 7z = 1 
The modulus operator (%) computes the remainder after dividing its first operand by its second.

Logic

OperatorActionExampleResult
&& Logical ANDtrue && false
true && true
false && false
false
true
false
||Logical ORtrue || false
true || true
false || false
true
true
false
!Logical NOTtrue && !falsetrue

Increment and Decrement

OperatorActionExampleResult
++Incrementa=1;
a++;
a = 2
––Decrementa=1;
a––;
a = 0;

Relational

OperatorActionExampleResult
==Equalsx = 1;
x == 1
true
!=NOT Equalsx = 1;
x != 1
false
<Less thanx = 1;
x < 2;
true
>Greater thanx = 1;
x > 0;
true
<=Less than or equal tox = 1;
x <= 0
false
>=Greater than or equal tox = 1;
x >= 5
false

Assignment

OperatorActionExampleResult
=Assignmentx = 1
+=Incremental Additiona=1;
a += 3;
a = 4;
-=Incremental Decrementa=1;
a -= 3;
a = -2;
*=Multiply bya=2;
a *= 4;
a = 8;
/=Divide bya=8;
a /= 2;
a = 4;
%=Modulus or Remaindera=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 << y"
>>=Right Shift"x >>= y" is equivalent to "x = x >> y"

others


OperatorActionExampleResult
&Logical ANDif (false & ++i == 1)false
|Logical OR true | false
false | false
true
false
^Logical Exclusive XORfalse ^ false
false ^ true
true ^ true
false
true
false
~Bitwise Complement x = ~0×00000000x = 0xffffffff
<<Left Shift1 << 12
>>Right Shift-1000 >> 3-125
??Default Valueint y = x ?? -1;if x = null y = -1 else y = x
:?Conditional Operatorcondition ? 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.
int x = 5;
 
if (x >= 3)
{
  Console.WriteLine("X is greater than or equal to 3.");
}
else
{
  Console.WriteLine("X is less than 3.");
}
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.
int x = 5;
 
if (x >= 3)
  Console.WriteLine("X is greater than or equal to 3.");
else
  Console.WriteLine("X is less than 3.");
You don't need to have an else statement. If all you want is to output something on Monday for example:
if (dayOfWeek == Monday)
  Console.WriteLine("Today is Monday");
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:
if (dayOfWeek == Monday)
  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");
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:
switch(dayOfWeek)
{
  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;
}
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:
case "Saturday":
  Console.WriteLine("Today is a Weekend"); // This will ERROR!
case "Sunday":
  Console.WriteLine("Today is a Weekend");
  break;
case "Saturday":
case "Sunday":
  Console.WriteLine("Today is a Weekend"); // This is OK!
  break;
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.
switch(dayOfWeek)
{
  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("This the weekend!!!");
    break;
}
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.

Examples

switch(dayOfWeek)
{
  case "Monday":
    Console.WriteLine("Today is Monday");
    break;
  case "Tuesday":
    return "Today is Tuesday";
    break;
  case "Wednesday":
    throw new Exception("Today is Wednesday");
    break;
  case "Thursday":
    goto case "Monday";
    break;
}

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.
int i = 1;
while (i <= 10)
{
  Console.WriteLine("Loop {0}", i);
  i++;
}
This will output:
Loop: 1
Loop: 2
Loop: 3
Loop: 4
Loop: 5
Loop: 6
Loop: 7
Loop: 8
Loop: 9
Loop: 10

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 which would be if you forgot to increment i within the loop. The exit condition 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.
int i = 12;
while (i <= 10)
{
  Console.WriteLine("Loop {0}", i);
  i++;
}

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.
int i = 1;
do
{
  Console.WriteLine("Loop {0}",i);
  i++;
} while (i <= 10);
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:
for (start value; end condition; increment counter)
{
  // Code to repeat
}
Looping from 1 to 10 as our first example will be coded as follows:
for (int i = 1; i <= 10; i++)
{
  // Code to repeat
}
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 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:
for (int i = 1; i <= 10; i++)
{
  i = 67; // This line will ERROR!
  Console.WriteLine("Loop: {0}", i);
}
Once the line in error 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.
string[] daysOfWeek = new string[] {
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday"
};
 
for (int i=0; i <= daysOfWeek.Length; i++)
{
  Console.WriteLine("Day of Week: {0}", daysOfWeek[i]);
}
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, such as forgetting that the an array index starts from 0 and the array length starts from 1. A foreach statement is a better in terms of readability and is less error prone, however there is a slight performance decrease compared with a for loop.
To iterate through the daysOfWeek array from the previous code, the for loop can be replaced with a foreach:
foreach(string Day in daysOfWeek)
{
  Console.WriteLine("Day: {0}", Day);
}
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, nor can you modify the daysOfWeek collection.

Loop Control

There are two statements that you can use to control the loop from the inside. The first will skip processing the current iteration and continue onto the next. Both of these keywords can be used in a while, for or foreach loop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i <= 10; i++)
            {
                if (i == 5)
                    continue;
 
                Console.WriteLine(i);
            }
        }
    }
}
This will output:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i <= 10; i++)
            {
                if (i == 5)
                    break;
 
                Console.WriteLine(i);
            }
        }
    }
}
Will output:
1
2
3
4
Press any key to continue . . .

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, and from there code is executed 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 debugger. 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:
class Program
{
    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 2;
    }
}
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.
namespace ConsoleApplication
{
  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:
  1. Select the project in Solution Explorer and bring up its properties.
  2. Click on the Application tab.
  3. Make sure that the Enable application framework check box is disabled.
  4. Change the value in the start-up object box to include /main:Program2 where 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.

 

Intermediate C# Tutorials

Arrays and Lists

Arrays are used to store collections of data in a numerical indexed list. Arrays can be one dimensional, multi-dimensional or jagged.
To start with we will look at a simple one dimensional array of integers.
An array is declared using brackets after the data type, with an element count in the brackets. Arrays in C# are of a fixed length, not dynamic. We will cover dynamic arrays (ArrayList and List) later in this tutorial.
int[] myIntArray = new int[10] // Create an array of 10 ints
Note: Although arrays are 0 indexed, which means that the first item in the array is 0, the second is 1 and so on, when declaring arrays you specify the total number of elements.
Arrays can be assigned to individually or in a loop:
int[] myIntArray = int[10];
myIntArray[0] = 0;
myIntArray[1] = 10;
myIntArray[2] = 20;
myIntArray[3] = 30;
 
// Assignment via loop
for (int i=0; i<myIntArray.Length; i++)
{
  myIntArray[i] = i * 10;
}
 
// Foreach loop over array
foreach (int element in myIntArray)
{
  Console.WriteLine("{0}", element);
}
Arrays can also be assigned to on declaration instead of specifying a length.
int[] myIntArray = {0,1,2,3,4,5,6,7};

Multi-dimensional Arrays

A multi-dimensional array consists of two or more elements that form a matrix. Jagged arrays are multi-dimensional arrays of arrays and covered later.
int myMultiArray = int[5,5];
int myOtherMultiArray = int[5,2];
Assignment and access is the same as a single dimensional array, but you need to specify both elements.
for (int y=0; y<=5; y++)
{
  for (int x=0; x<=5; x++)
  {
    myMultiArray[x,y] = x * y;
  }
}
 

Jagged Arrays

Jagged arrays, or array of arrays, are multi-dimensional arrays that consist of arrays as the elements.
int[][] myJaggedArray = new int[2][];
 
myJaggedArray[0] = new int[5];
myJaggedArray[1] = new int[] {0, 1, 2, 3, 4, 5, 6, 7}

Array Methods

All arrays are objects that inherit methods and properties from the base Array class. These can be used to determine the number of items in an array (Length) and the number of dimensions (Rank).

Array Lengths

Once an array is declared with a number of elements, its length cannot be changed. If you need more than the number of elements declared you will have to create another array. You cannot redeclare an array in C#.
int[] myIntArray = new int[10];
int[] myLargerIntArray = new int[20];
 
myIntArray.CopyTo(myLargerIntArray, 0);
One solution to this problem is to use a List or an ArrayList, which are much more powerful than simple arrays.

ArrayList and List

Not available in .Net 1
An ArrayList is a class that holds values like an array, but elements can be added or removed at will (dynamic array). They offer greater functionality over an array, but they also have a larger overhead. ArrayLists are not type safe, meaning that each element of the ArrayList can be of a different type.
using System.Collections.ArrayList;
ArrayList myArrayList = new ArrayList();
Exception ex = new Exception("My Demo Exception");
 
myArrayList.Add("Hello");
myArrayList.Add("World");
myArrayList.Add(10);
myArrayList.Add(ex);
 
foreach (Object obj in myArrayList)
{
  Console.WriteLine(obj.ToString());
}
 
/* Output:
Hello
World
10
System.Exception: My Demo Exception
/*
A List is a type safe version of an ArrayList.
using System.Collections.Generic;
 
List<string> myList = new List<string>();
 
myList.Add("Hello");
myList.Add("World");
myList.Add(10); // Compiler Error
 
 
Note: the value in angle brackets is the type that the list will contain. Also note the parenthesis at the end of the declaration statement. Type can be any type of object defined in C# including classes.
Both ArrayList and List support searching and sorting methods.

Advanced Data Types

In previous tutorials we saw the ArrayList and the List data types, in this tutorial we will look at other advanced data types such as Hashtables, Dictionaries, Enums, and String vs StringBuilder

Hashtables

Hashtables are a named key List where you define a key and a value when setting and getting values. Hashtables are not type safe, so the key and value are of type object. You can access the data using the named key as the index, however you will have to check and cast the value.
using System;
using System.Text;
using System.Collections;
 
class Program
{
    static void Main()
    {
        Hashtable myHashTable = new Hashtable();
 
        myHashTable.Add("bob", 27);
        myHashTable.Add(33, "fred");
 
        int theAge = (int)myHashTable["bob"];
    }
}
In order to iterate through hashtable elements you must create a IDictionaryEnumerator interface to retrieve the key and the value.
IDictionaryEnumerator myEnumerator = new myHashTable.GetEnumerator();
 
while (myEnumerator.MoveNext())
{
  Console.WriteLine("{0}: {1}", myEnumerator.Key, myEnumerator.Value);
}
You can also use a foreach loop like this:
foreach (string key in myHashTable.Keys)
{
  Console.WriteLine(key + '=' + myHashTable[key]);
}

Dictionary

A dictionary is a type safe version of the Hashtable. Like a List<> object, you need to specify the type for both the key and the value.
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
 
class Program
{
    static void Main()
    {
        Dictionary<string, int> myDictionary = new Dictionary<string, int>();
 
        myDictionary.Add("bob", 27);
        myDictionary.Add("fred", 33);
 
        int theAge = myDictionary["bob"];
    }
}

Enums and Flags

An enum or enumerate is a set consisting only of defined constants. They are useful for limiting the values that a type can contain.
enum daysInWeek {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};
Each item in the set is assigned a numerical value, in this example Monday equals 1 and Sunday = 7. You can specify your own values using the equals symbol followed by a numeric.
enum daysInWeek {Monday=0, Tuesday=2, Wednesday=4, Thursday, Friday, Saturday, Sunday};
Values that have not been explicitly assigned a value take the value of the previous item plus one, thus Thursday will equal 5.
Enums can be used as constants to ensure that only the specified values are allowed.
int day = daysInWeek.Wednesday;
 
if (day == daysInWeek.Thursday)
{
  Console.WriteLine("Today is Thursday");
}
Enums can also be used to define a binary set, that is a value that holds various options about something using the [Flags] attribute. These are useful where there are many boolean options that an object can have and cut down on the number of properties that a call will have.
bool hasButtons = true;
bool hasZip = false;
bool hasPockets = false;
bool hasEmbrodery = true;
Re-written using enum bit flags gives:
 
[Flags]
public enum garmentOptions
{
  hasButtons = 0x01,   // 00000001  1
  hasZip = 0x02,       // 00000010  2
  hasPockets = 0x04,   // 00000100  4
  hasEmbrodery = 0x08; // 00001000  8
}
 
garmentOptions myGarment = garmentOptions.hasButtons | garmentOptions.hasEmbrodery;
 
// result of myGarment is 9 or:
//   00000001  1
// + 00001000  8
// = 00001001  9
 
if ((myGarment & garmentOptions.hasEmbrodery) > 0)
{
  // Embrodery specific code here
}
The logical bitwise & is used to test if an enum bit flag is part of the set in myGarment.

String vs StringBuilder

A string data type is an immutable type; meaning that once it is created it cannot be changed. Strange, you may think, I do that all the time…
string name = "bob";
name = name + " smith";
name += " jr";
While the compiler sees no problems with this, its not the most efferent method. Since the string object cannot be changed, the CLR will create a new string object, assign it the value of the old one plus the extra data, then dispose of the old object. If you are doing multiple operations, such as building up a result string, then this method represents a performance overhead that can be eliminated by using a StringBuilder.
StringBuilders allow the string to be manipulated without objects being created and disposed of each time. They can then be converted back to a string when needed.
StringBuilder myStringBuilder = new StringBuilder();
 
myStringBuilder.Append("bob");
myStringBuilder.Append(" smith");
myStringBuilder.Append(" jr");
 
string myString = myStringBuilder.ToString();
There is a huge performance hit when appending to a string, and the speed increase from using a string builder is surprising. You can have a look at the performance increase by running this short piece of code. It will append a fullstop to the previous string 100000 times.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string myString = "";
            StringBuilder mySb = new StringBuilder();
 
            Console.WriteLine("String Start: {0}", System.DateTime.Now);
 
            for (int i = 0; i < 100000; i++)
            {
                myString += ".";
            }
 
            Console.WriteLine("String End: {0}", System.DateTime.Now);
            Console.WriteLine("StringBuilder Start: {0}", System.DateTime.Now);
 
            for (int i = 0; i < 100000; i++)
            {
                mySb.Append(".");
            }
 
            Console.WriteLine("StringBuilder End: {0}", System.DateTime.Now);
        }
    }
}
 
String Start: 11/11/2011 20:57:56
String End: 11/11/2011 20:58:12
StringBuilder Start: 11/11/2011 20:58:12
StringBuilder End: 11/11/2011 20:58:12
Press any key to continue . . .

 

Method Overloading and Overriding

When inheriting from another class, you may wish to change the default behaviour of a method or create a different method signature. You can do this by overloading the method with your own code.
Method signatures are formed from the parameter list, in particular the data types. Methods can share the same name within the class as long as the signature is different.
static int Add(int a, int b)
{
  return a + b;
}
In the above example the signature should be (int, int). In the Visual Studio code editor, if you were to call the Add method, after you enter the '(' IntelliSense will pop-up the available parameters. Notice that there is only one option given to you.

Method Overloading

We can add an overloaded method with a different signature and IntelliSense will now present two options, one for each signature of the overloaded method. The compiler finds two methods of the same name and two calls to that method with different parameters. It is able to tell the difference by comparing the signatures of the methods.
static int Add(int a, int b, int c)
{
  return a + b + c;
}
The names of the parameter and the return type have no effect on the method signature.
static decimal Add(int a, int b, int c)
{
  return a + b + c;
}
The above method will raise an error because a method already exists for Add(int, int), even though it returns a decimal.
Methods should be overloaded when you have similar methods that require differing parameters or you want to add new functionality to existing code, however you should not use overloading to often as it causes headaches during debugging and testing and is more effort to maintain.

Optional Parameters in C#

C# does not have an implementation of optional parameters like those found in PHP, however you can simulate this feature using method overloading.
static int Add(int a, int b)
{
  return Add(a, b, 0, 0);
}
 
static int Add(int a, int b, int c)
{
  return Add(a, b, c, 0);
}
 
static int Add(int a, int b, int c, int d)
{
  return (a + b + c + d);
}
Overloading Example
In this example we can call Add with 2, 3 or 4 parameters and only one functional method is called – the others just pass the data around. You can use IntelliSense to see the different overloads and their parameters.

Full Code

using System;
using System.Drawing;
 
class TestBaseCarClass
{
    static void Main()
    {
        Console.WriteLine(Add(1, 1));
    }
 
    static int Add(int a, int b)
    {
        return Add(a, b, 0, 0);
    }
 
    static int Add(int a, int b, int c)
    {
        return Add(a, b, c, 0);
    }
 
    static int Add(int a, int b, int c, int d)
    {
        return a + b + c + d;
    }
}
 
NB. This code is only shown as an example. If you really want to create a function that accepts any number of parameters of the same type, then the params keyword is better suited.

Method Overriding

Methods can be overridden, replacing the default behaviour or extending it. In this example we will override the ToString() method for the ArrayList class so that it may return something more meaningful.
using System;
using System.Collections.Generic;
 
class Program
{
  static void Main()
  {
     ArrayList myList = new ArrayList();
 
    myList.Add("Hello");
    myList.Add("World");
    myList.Add("123456");
 
    Console.WriteLine(myList.ToString());
  }
}
You may expect the ToString to return "Hello World 123456″, but it actually returns "System.Collections.ArrayList", which isn't particularly helpful.
We can override this default behaviour by creating a new class, which inherits from the ArrayList. We can then override the ToString method by using the override keyword.
class myArrayList : System.Collections.ArrayList
{
    public override string ToString()
    {
        return base.ToString();
    }
}
The base keyword is used to refer to the object. By default the override method will return base.ToString(). You can use this base object to call the non-overwritten method. We are going to amend the code to suit our needs, and in this example we are going to convert the array list to show the contents of the list, one item per line.
using System;
using System.Text;
using System.Collections.Generic;
 
class Program
{
    static void Main()
    {
        myArrayList myList = new myArrayList();
 
        myList.Add("Hello");
        myList.Add("World");
        myList.Add("123456");
 
        Console.WriteLine(myList.ToString());
    }
}
 
class myArrayList : System.Collections.ArrayList
{
    public override string ToString()
    {
        StringBuilder result = new StringBuilder();
        string[] theItems = (string[])base.ToArray(typeof(string));
 
        foreach (string item in theItems)
        {
            result.AppendLine(item);
        }
        return result.ToString();
    }
}
Now when we create an instance of our new class and call the ToString method we are given "Hello World 123456″ one item per line.
In Visual Studio 2005 onwards you can get the IDE to create the code for the override for you. Create the class and public override then select the method from the list. It will then fill in the remainder of the code and default return for you.

 

Operator Overloading

Operators can be overloaded as well as methods, a technique that allows custom data types to be manipulated in the same way as a normal data type.
Lets say you create a bank account class, for simplicity it will only contain a balance and holder name.
public class bankAccount
{
  decimal balance;
  string holdersName;
}
 
public class Program
{
  static void Main()
  {
    bankAccount testAccount1 = new bankAccount();
    bankAccount testAccount2 = new bankAccount();
 
    testAccount1.balance = 10.0;
    testAccount1.holdersName = "Bob Smith";
 
    testAccount2.balance = 20.0;
    testAccount2.holdersName = "Jane Doe";
  }
}
If you wanted to add testAccount2 to testAccount1 you may be tempted to try:
testAccount1 = testAccount1 + testAccount2
or even
testAccount1 += testAccount2
You will find that the compiler will not let you add these together as it does not know how to handle the operators for this custom type. We can tell the C# compiler how to add two bank accounts together by overloading the operators.
public class bankAccount
{
  public decimal balance;
  public string holdersName;
 
  public static bankAccount operator +(bankAccount b1, bankAccount b2)
  {
    bankAccount temp = new bankAccount();
    temp.balance = b1.balance + b2.balance;
    temp.holdersName = b1.holdersName + " and " + b2.holdersName;
    return temp;
  }
}
This will allow the use of the + operator on the bankAccount class. It will return a bankAccount, which contains the sum of the two balances and the two holders names concatenated.
All the other operators can be overloaded in the same way; all you need to do is provide your own logic within the method.
testAccount1 = testAccount1 + testAccount2;
 
// testAccount1.ballance = 30
// testAccount1.holdersName = "Bob Smith and Jane Doe"
Obviously this is not how bank accounts are merged, but it gives an illustration of how operators can be overloaded for custom data types.

 

Error and Exception Handling

Critical errors are called Exceptions and they are raised whenever the compiler encounters a problem with a segment of code. Example of common exceptions are divide by zero and reading a null value.
Exceptions can be managed using a try…catch…finally block of code. These will catch any errors and allow your code to handle the error and deal with them without the users knowledge. Exception handling prevents errors from crashing applications causing data loss.
Traditionally in C, methods and functions would return the error code in the function result. A value of false or -1 usually indicated an error with the method. This caused a few problems, most notably that of returning a value back from a functions, and programmers usually did not test the result code. Also -1 or false could be the result of the function, not necessarily an error, so it was a little confusing.
In the .Net platform we have exceptions, which are System objects that represent a specific or generalised error condition.

Catching an Exception

using System;
using System.Collections.Generic;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = 0;
            int y = 0;
            y = 100 / x;
        }
    }
}
Obviously this line of code will cause a exception as you cannot divide any number by 0. If left like this the program will crash and stop working, requiring the user to reload the application. The solution to this is to implement a try…catch…finally block.
Try, catch and finally are three essential code blocks for problem free programs. The logic of the block is that we try to do x, catch an error if one occurs, and finally do y.
If an exception is raised in the try block then the code in the catch block is run. The catch block could call logging or reporting methods, corrective actions or alternative code. Code in the finally block is always executed regardless of an error or not. This block should close files or connections, free memory etc..
Using the divide by zero error above, with a try…catch block implemented it now looks like this.
using System;
using System.Collections.Generic;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = 0;
            int y = 0;
 
            try
            {
                y = 100 / x;
            }
            catch
            {
                Console.WriteLine("There was an error but we caught it!");
                Console.WriteLine("Please enter a new number:");
                y = int.Parse(Console.ReadLine());
            }
        }
    }
}
Should an error occur within the try block, in this example y = 100 / x, the code within the catch block will be executed, in which you should attempt to fix the problem, notify or log the error and gracefully exit the program if required.
let's have a look at a different example, and see what code gets executed and what code is skipped over. We will also see the finally block in action. In the first example there is no error handling.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string filename = "c:\\sharpertutorials\\orders.csv";
            StreamReader myFile = new StreamReader(filename);
            string orders = myFile.ReadToEnd();
            myFile.Close();
 
            Console.WriteLine(orders);
        }
    }
}
When executed, the file path does not exist, so when we try and open the file an exception is raised.
Error and Exception Handling
As soon as the error occurs, the program cannot continue to run, the user is presented with a horrible error message and the program is forced to close. Not a very good impression.
A better solution is to use a try…catch block to handle the error.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string filename = "c:\\sharpertutorials\\orders.csv";
            string orders = string.Empty;
            StreamReader myFile = null;
 
            try
            {
                myFile = new StreamReader(filename);
                orders = myFile.ReadToEnd();
                myFile.Close();
            }
            catch
            {
                Console.WriteLine("Sorry, an error has occurred.");
            }
 
            Console.WriteLine(orders);
        }
    }
}
Notice how the variable declarations have been taken outside the try block. This is because we need the variables to be in the scope of the method not just the code block.
When the code is now run, the screen shows a friendly, but rather unhelpful, error message. Luckily there is a solution to this problem! The catch block can take in a parameter which will hold details about the error, so in our example a DirectoryNotFoundException was raised.
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string filename = "c:\\sharpertutorials\\orders.csv";
            string orders = string.Empty;
            StreamReader myFile = null;
 
            try
            {
                myFile = new StreamReader(filename);
                orders = myFile.ReadToEnd();
                myFile.Close();
            }
            catch(DirectoryNotFoundException ex)
            {
                Console.WriteLine("Sorry, the path to '" + filename + "' does not exist. Please correct the error and try again.");
            }
 
            Console.WriteLine(orders);
        }
    }
}
Now when the program is run the user have a detailed message telling them what the error is and how to fix it. Let's fix the error by creating the directory and re-run the program.
Error and Exception Handling
Another unhandled exception! This time the orders.csv file does not exist and we have a FileNotFoundException. We can implement multiple catch blocks, one for each type of exception we want to capture.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string filename = "c:\\sharpertutorials\\orders.csv";
            string orders = string.Empty;
            StreamReader myFile = null;
 
            try
            {
                myFile = new StreamReader(filename);
                orders = myFile.ReadToEnd();
                myFile.Close();
            }
            catch (DirectoryNotFoundException ex)
            {
                Console.WriteLine("Sorry, the path to '" + filename + "' does not exist. Please correct the error and try again.");
            }
            catch (FileNotFoundException ex)
            {
                Console.WriteLine("Sorry, the file '" + filename + "' does not exist. Please create the file and try again.");
            }
 
            Console.WriteLine(orders);
        }
    }
}
This time the user will get another message telling them the cause of the problem and the solution. Now we have a valid file and path, let's try and do something with the data read in from the file.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string filename = "c:\\sharpertutorials\\orders.csv";
            string orders = string.Empty;
            string data = string.Empty;
            StreamReader myFile = null;
 
            try
            {
                myFile = new StreamReader(filename);
                orders = myFile.ReadToEnd();
 
                data = orders.Substring(0, 1);
 
                myFile.Close();
            }
            catch (DirectoryNotFoundException ex)
            {
                Console.WriteLine("Sorry, the path to '" + filename + "' does not exist. Please correct the error and try again.");
            }
            catch (FileNotFoundException ex)
            {
                Console.WriteLine("Sorry, the file '" + filename + "' does not exist. Please create the file and try again.");
            }
 
            Console.WriteLine(data);
        }
    }
}
Again, we have another error! Because the file was empty and we tried to do a substring on an empty string we get a ArgumentOutOfRangeException and the program will force close. It gets worse though, since we have opened a file and the program has closed before we closed it! This can lead to all kinds of trouble, even more so if it was a database we were connecting to. The solution is the finally block. Code in the finally block is always guaranteed to run so we can use that to close any files or connections.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string filename = "c:\\sharpertutorials\\orders.csv";
            string orders = string.Empty;
            string data = string.Empty;
            StreamReader myFile = null;
 
            try
            {
                myFile = new StreamReader(filename);
                orders = myFile.ReadToEnd();
 
                data = orders.Substring(0, 1);
            }
            catch (DirectoryNotFoundException ex)
            {
                Console.WriteLine("Sorry, the path to '" + filename + "' does not exist. Please correct the error and try again.");
            }
            catch (FileNotFoundException ex)
            {
                Console.WriteLine("Sorry, the file '" + filename + "' does not exist. Please create the file and try again.");
            }
            finally
            {
                myFile.Close();
            }
 
            Console.WriteLine(orders);
        }
    }
}
There we have a complete functioning try…catch…finally block. Hopefully you can see how and why this is an essential part of trouble free programming and how it can be used to avoid unhelpful and meaningless error messages.

Raising or Throwing an Exception

Exceptions can be manually thrown in your code, either for testing or to signal a fault that needs to be dealt with. It is important to validate inputs and notify errors, especially when dealing with untrusted code – such as that developed by another programmer. In this example the scenario is that we are developing a class to handle mathematical operations. Another developer will be using this class in their program. For simplicity I have included both classes in the same project.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
 
namespace ConsoleApplication1
{
    // Writen by us
    static class MyMathClass
    {
        public static decimal Divide(int x, int y)
        {
            return x / y;
        }
    }
 
 
    // Writen by somebody else    
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(MyMathClass.Divide(10, 0));
        }
    }
}
Here we can see that our class and method are fine. It will divide the first parameter by the second. What can go wrong? Well the other programmer is an "untrusted" source. They can pass in a valid number that causes our code to crash. In this example a divide by zero error. Since our code is the one that crashed, the fault and blame is ours.
Exception and Error Handling
What we can do to avoid this is validate the inputs and raise an exception that will be handled by their code. This means that if they pass in invalid data to our method, their code is at fault leaving us blame free. Raising an exception is done using the throw keyword. For a list of available exceptions you can throw, please click on Debug menu -> Exceptions… or press Ctrl+D, E. You can also create your own exceptions in the next section.
You can either throw a new exception and use the default message, or you can specify a more specific error message in the constructor, as shown below.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
 
namespace ConsoleApplication1
{
    // Writen by us
    static class MyMathClass
    {
        public static decimal Divide(int x, int y)
        {
            if (y == 0)
                throw new ArgumentOutOfRangeException("Parameter y cannot be 0!");
 
            return x / y;
        }
    }
 
 
    // Writen by somebody else    
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(MyMathClass.Divide(10, 0));
        }
    }
}
Now when the program is run the calling method will receive a ArgumentOutOfRangeException message with our custom error message.

Custom Exceptions

If there is not a predefined exception that suits your needs, you can easily create a new custom exception by simply creating a class that inherits from any of the predefined exception classes or the base Exception class. They can be used in the same way as a normal exception.
class myException : System.Exception
{
}
 
class Program
{
  static void Main()
  {
    throw new myException("Custom Exception");
  }
}

Exception Guidelines

When throwing exceptions you should avoid exceptions for normal or expected cases. These should be handled through proper program logic.
Never create and throw objects of class Exception, its much better to throw exceptions of the most specific class possible as it will give you greater flexibility in catching the exception and handling it. Should an unhandled exception occur, the more specific exception class will give you a better idea of where to start debugging. You should also include a description string in an Exception object with details about the error.
When catching exceptions, arrange catch blocks from specific to general otherwise the general exception will always be caught and the specific catch blocks will never be processed. Do not let exceptions go unhandled in the Main method as this will cause the application to crash and the user will not be able to recover from the error.
Never use an empty catch block – what is the point?
try
{
  x = new StreamReader(filename);
}
catch
{
}
 
Console.WriteLine(x.ReadToEnd());

 

Using Namespaces

In this tutorial we will have a look at Namespaces. What are they? and How can we use them? Why do we use them?
In the previous tutorials we used the System namespace directive, using System; We will now look in more detail at namespaces and how they can be used.
The entire .Net framework is built using namespaces, the most important of which is System. A Namespace is a construct that can be used to organise sections of code, be it classes, structs, other namespaces or even entire solutions. Namespaces are used to avoid code conflicts and to group together classes of similar functionality. It is good practice to implement namespaces in your projects, as it will aid code reuse in later projects.

Standard Namespaces

In the previous tutorial we used the System namespace. Lets have a play with our Hello World application in Visual Studio. Launch Visual Studio from the Start Menu, and create a new console project (File » New » Project… » Visual C# » Windows » Console)
Delete all the code on the screen and paste in the Hello World code from before. For convenience it is listed again below.
using System;
 
class HelloWorld
{
  static void Main()
  {
    Console.WriteLine("Hello World!");
  }
}
Listing 1-1
Press Ctrl+Shift+B to build the project or select Build Solution from the Build menu. The output window should show:
using System;
 
namespace MyHelloWorld
{
  class HelloWorld
  {
    static void Main()
    {
      Console.WriteLine("Hello World!");
    }
  }
}
Listing 1-2
Its that easy! Just surround your classes with a namespace block and you're done.
In fact it can be even easier with a nice feature of the IDE. Simply select your classes you wish to include in the namespace right click the code with the mouse and select "Surround With…" and type namespace. The IDE will automatically add in the namespace construct, braces and indent the code for you!

Avoid Conflicts

Namespaces are primarily used for avoiding code conflicts. You could have two developers working on different parts of the same project. They could potentially use the same class name for something inadvertently, and namespaces would be able to resolve the correct class.
Alternatively, you could be using third party software from two companies, and they could use the same class names. Each different class with the same name would perform a slightly different function.

Example

This very simple example illustrates the use of two classes of the same name, which each have a function of the same name. By referencing the namespace you can access the other classes methods directly and unambiguously.
using System;
 
namespace myInhouseCode
{
    class myClass
    {
        static void Main()
        {
            Console.WriteLine("myInhouseCode Main");
            myMethod();
            myContractorsCode.myClass.myMethod();
            Console.ReadLine();
        }
 
        static void myMethod()
        {
            Console.WriteLine("myMethod Called From myInhouseCode");
        }
    }
}
 
namespace myContractorsCode
{
    class myClass
    {
        public static void myMethod()
        {
            Console.WriteLine("myMethod Called from myContractors Code");
        }
    }
}
Listing 1-3, Multiple Namespaces
The output of this code is as follows:
Multiple Namespaces
In this example we can see that although we have two classes of the same name, and two methods of the same name, by using namespaces we can avoid conflicts, as namespaces allow us to explicitly find the function we require.

Another example of Using

In this final example we can see that our contractor has created a method in a class in a namespace. We are going to call it from our Main method.
using System;
 
namespace myInhouseCode
{
    class myClass
    {
        static void Main()
        {
            myContractorsCode.myContractorsClass.myContractorsMethod();
            Console.ReadLine();
        }
    }
}
 
namespace myContractorsCode
{
    class myContractorsClass
    {
        public static void myContractorsMethod()
        {
            Console.WriteLine("myContractorsMethod");
        }
    }
}


myContractorsCode.myContractorsClass.myContractorsMethod(); is a bit long winded, even with IntelliSense, so we can shorten this a little by adding using myContractorsCode; to the using directives and remove the myContractorsCode from the calling statement. This makes our code a little easier to read and type.

Full Example Listing

using System;
using myContractorsCode;
 
namespace myInhouseCode
{
    class myClass
    {
        static void Main()
        {
            myContractorsClass.myContractorsMethod();
            Console.ReadLine();
        }
    }
}
 
namespace myContractorsCode
{
    class myContractorsClass
    {
        public static void myContractorsMethod()
        {
            Console.WriteLine("myContractorsMethod");
        }
    }
}

Summary and Conclusions

We have seen namespaces and we now know how they can be used to group together classes in a file. We have also seen how we can use the using directive to tell the compiler where to find code and to make our lives a little easier as well.







Advanced C# Tutorials

Comming Soon
















 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Best Buy Coupons