Showing posts with label csharp. Show all posts
Showing posts with label csharp. Show all posts

Step By Step CSharp Tutorials for Beginners

Step By Step CSharp Tutorials for Beginners

This is C# tutorial. In this tutorial you will learn the basics and some advanced topics of the C# language. The tutorial is suitable for beginners and intermediate programmers.

Table of Contents

C#

C# is a modern, high-level, general-purpose, object-oriented programming language. It is the principal language of the .NET framework. The design goals of the language were software robustness, durability and programmer productivity. It can be used to create console applications, GUI applications, web applications, both on PCs or embedded systems.
Continue Reading

Latest New features of CSharp

Latest New features of CSharp

the following new features to the language:
  • Dynamic programming
  • Named parameters
  • Optional parameters
  • Covariance and Contravariance

Dynamic programming

This new version of the C# language brought a new type dynamic. Once a variable is declared as having type dynamic, operations on these value are not done or verified at compile time, but instead happen entirely at runtime. This is known also as duck typing. The name of the concept refers to the duck test, which may be phrased as follows: "When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck". In other words, we are concerned about what the object is doing rather than with the type of the object. The dynamic type is used to simplify access to COM objects, IronPython and IronRuby libraries and to the HTML DOM.
using System;


public class Duck
{
public void quack()
{
Console.WriteLine("Quaaaack");
}
}

public class Person
{
public void quack()
{
Console.WriteLine("Person imitates a duck");
}
}


public class CSharpApp
{
static void Main()
{
Duck donald = new Duck();
Person josh = new Person();

InTheForest(donald);
InTheForest(josh);
}

public static void InTheForest(dynamic duck)
{
duck.quack();
}
}
In our example, we have two classes. The Duck class and the Person class. Both have the quack() method.
public static void InTheForest(dynamic duck)
{
duck.quack();
}
The InTheForest() method has a dynamic parameter. The type of the object is not important; we are concerned about capabilities of the objects. If objects passed to the InTheForest() method can invoke the quack() method, than we are fine.
$ dmcs ducktyping.cs
$ /usr/local/bin/mono ducktyping.exe
Quaaaack
Person imitates a duck
We compile and run the program. We use the Mono dmcs compiler, that is shipped with the Mono 2.8 and supports the C# 4.0 profile.

Named parameters

In earlier versions of the C# language, the arguments were provided in the order in which they appeared in the method's signature. And the position in the parameter list is important when evaluating a method. Named arguments enable us to specify the method parameters by their names. When specifying the named arguments, the position of the parameter is not important anymore.
using System;


public class CSharpApp
{
static void Main()
{
ShowMessage(name: "Jane", age: 17);
}

public static void ShowMessage(int age, string name)
{
Console.WriteLine("{0} is {1} years old", name, age);
}
}
A simple example with named arguments.
ShowMessage(name: "Jane", age: 17);
The parameter name is followed by the colon (:) character and the value. The parameters may not be specified in order of the method signature.
$ /usr/local/bin/mono named.exe 
Jane is 17 years old
Output.

Optional parameters

With C# 4.0 there are required parameters and optional parameters. Any call must provide arguments for all required parameters, but can omit arguments for optional parameters. Optional parameters are defined at the end of the parameter list, after any required parameters. An optional parameter is created, when when a default value is specified for the parameters.
using System;


public class CSharpApp
{
static void Main()
{
Power(4, 4);
Power(5);
}

public static void Power(int x, int y=2)
{
int z = 1;

for (int i=0; i<y; i++)
{
z *= x;
}

Console.WriteLine(z);
}
}
An example for an optional argument. We have a Power() method. The method takes two parameters; the base and the exponent. If we do not specify the exponent, than the default 2 is used.
public static void Power(int x, int y=2)
In the method definition, we have a required x parameter and the optional y parameter. The optional y has a default value.
Power(4, 4);
Power(5);
When we call the Power() method, we can specify one or two parameters.
$ /usr/local/bin/mono optional.exe 
256
25
Output of the example.

Covariance & contravariance

C# version 4.0 brings covariance for generics and delegate types. They were introduced because they bring flexibility to programming. Within the type system of a programming language, covariance and contravariance refers to the ordering of types from narrower to wider and their interchangeability or equivalence in certain situations (such as parameters, generics, and return types). (wikipedia)

Types that are
  • covariant: convert from wider (double) to narrower (float).
  • contravariant: convert from narrower (float) to wider (double).
  • invariant: are not able to convert (Null).
using System;


public class CSharpApp
{
static void Main()
{
string[] langs = {"C#", "Python", "PHP", "Java"};
object[] objs = langs;

object o1 = objs[1];
Console.WriteLine(o1);
}
}
Arrays are covariant from the beginning.
string[] langs = {"C#", "Python", "PHP", "Java"};
We have an array of string.
object[] objs = langs;
We assign a wider array of strings to a narrower object type.
object o1 = objs[1];
Console.WriteLine(o1);
We get an item and print it to the console.
$ ./covariance.exe 
Python
Output of the array covariance example.

In the following example, we have a covariance for generics.
using System;
using System.Collections.Generic;


public class CSharpApp
{
static void Main()
{
IEnumerable<string> strings = new List<string>() {"1", "3", "2", "5"};
PrintAll(strings);
}

static void PrintAll(IEnumerable<object> objects)
{
foreach (object o in objects)
{
System.Console.WriteLine(o);
}
}
}
We have a generic list of strings. We call then the PrintAll() method, which prints all the elements of the list. Note that the method parameter has a less derived type parameter that our generic list.
$ /usr/local/bin/mono covariance2.exe 
1
3
2
5
Output.

The following is an example for a covariance in delegates.
using System;
using System.Collections.Generic;


public class CSharpApp
{
static void Main()
{
Action<string> del = ShowMessage;
del("Proximity alert");
}

static void ShowMessage(object message)
{
Console.WriteLine(message);
}
}
We assign a method which has a narrower parameter type to a delegate, which has a wider parameter type.
$ /usr/local/bin/mono contravariance.exe 
Proximity alert
Output.
This part of the C# tutorial we have talked about new features
Continue Reading

CSharp New Features

CSharp new features

the following new features to the language:
  • Implicitly typed variables
  • Implicitly typed arrays
  • Object & collection initializers
  • Automatic properties
  • Anonymous types
  • Extension methods
  • Query expressions
  • Lambda expressions
  • Expression trees
Query expressions, lambda expressions and expression trees are beyond the scope of this tutorial. They are closely connected to the LINQ.

Implicitly typed local variables & arrays

Both implicitly typed local variables & arrays are connected with the var keyword. It is an implicit data type. In some cases, we do not have to specify the type for a variable. This does not mean, that C# is partially a dynamic language. C# remains a statically and strongly typed programming language. Sometimes, when the usage of the var keyword is allowed, the compiler will find and use the type for us.
In some cases, the var keyword is not allowed. It can be used only on a local variable. It cannot be applied on a field in a class scope. It must be declared and initialized in one statement. The variable cannot be initialized to null.
using System;

public class CSharpApp
{
static void Main()
{
int x = 34;
var y = 32.3f;

var name = "Jane";

Console.WriteLine(x);
Console.WriteLine(y.GetType());
Console.WriteLine(name.GetType());
}
}
We have a small example, where we use the var type.
int x = 34;
var y = 32.3f;
The first variable is explicitly typed, the second variable is implicitly typed. The compiler will look at the right side of the assignment and infer the type of the variable.
Console.WriteLine(y.GetType());
Console.WriteLine(name.GetType());
These two lines will check the type of the two variables.
$ ./itlv.exe 
34
System.Single
System.String
As we can see, the two variables use the familiar, built-in data types.

Implicitly typed arrays Implicitly typed arrays are arrays, in which the type of the array is inferred from the elements of the array in the array initializer by the compiler. The rules are the same as for implicitly typed local variables. Implicitly typed arrays are mostly used in query expressions together with anonymous types and object and collection initializers.
using System;

public class CSharpApp
{
static void Main()
{
var items = new[] { "C#", "F#", "Python", "C" };

foreach (var item in items)
{
Console.WriteLine(item);
}
}
}
An example demonstrating the implicitly typed arrays.
var items = new[] { "C#", "F#", "Python", "C" };
We again use the var keyword. The square brackets on the left side are omitted.
foreach (var item in items)
{
Console.WriteLine(item);
}
The foreach loop is used to traverse the array. Note the use of the local implicitly typed item variable.
$ ./ita.exe 
C#
F#
Python
C
Output.

Object initializers

Object initializers give a new syntax for creating and initiating objects. Inside a pair of curly brackets {} we initiate members of a class through a series of assignments. They are separated by comma character.
using System;

public class Person
{
private string _name;
private int _age;

public string Name
{
get { return _name; }
set { _name = value;}
}

public int Age
{
get { return _age; }
set { _age = value;}
}

public override string ToString()
{
return String.Format("{0} is {1} years old", _name, _age);
}
}

public class CSharpApp
{
static void Main()
{
Person p1 = new Person();
p1.Name = "Jane";
p1.Age = 17;

Person p2 = new Person { Name="Becky", Age=18 };

Console.WriteLine(p1);
Console.WriteLine(p2);
}
}
In the above example, we have a Person class with two properties. We create two instances of this class. We use the old way and we also use the object initializer expression.
public string Name
{
get { return _name; }
set { _name = value;}
}
This is a Name property, with set a get accessors.
Person p1 = new Person();
p1.Name = "Jane";
p1.Age = 17;
This is the old way of creating an object and initiating it with values using the field notation.
Person p2 = new Person { Name="Becky", Age=18 };
This is the object initializer. Inside curly brackets, the two members are initiated.

Collection initializers

Collection initializers are a way of initiating collections, where the elements of a collection are specified inside curly brackets.
List <string> planets = new List<string>();

planets.Add("Mercury");
planets.Add("Venus");
planets.Add("Earth");
planets.Add("Mars");
planets.Add("Jupiter");
planets.Add("Saturn");
planets.Add("Uranus");
planets.Add("Neptune");
This is the classic way of initiating a collection. In the following example, we will use a collection initializer for the same generic list.
using System;
using System.Collections.Generic;

public class CSharpApp
{
static void Main()
{
List <string> planets = new List <string>
{"Mercury", "Venus", "Earth", "Mars", "Jupiter",
"Saturn", "Uranus", "Neptune"};


foreach (string planet in planets)
{
Console.WriteLine(planet);
}
}
}
We create a generic list of planets.
List <string> planets = new List <string> 
{"Mercury", "Venus", "Earth", "Mars", "Jupiter",
"Saturn", "Uranus", "Neptune"};
This is the collection initializer expression. The planet names are specified between the curly brackets. We save a some typing. We do not need to call the Add() method for each item of the collection.
$ ./collectioninitializers.exe 
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Neptune
Output.

Automatic properties

In a software project, there are lots of simple properties, that only set or get some simple values. To simplify programming and to make the code shorter, automatic properties were created. Note that we cannot use automatic properties in all cases. Only for the simple ones.
using System;


public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}

public class CSharpApp
{
static void Main()
{
Person p = new Person();
p.Name = "Jane";
p.Age = 17;

Console.WriteLine("{0} is {1} years old",
p.Name, p.Age);
}
}
This code is much shorter. We have a person class in which we have two properties.
public string Name { get; set; }
public int Age { get; set; }
Here we have two automatic properties. There is no implementation of the accessors. And there are no member fields. The compiler will do the rest for us.
Person p = new Person();
p.Name = "Jane";
p.Age = 17;

Console.WriteLine("{0} is {1} years old",
p.Name, p.Age);
We normally use the properties as usual.
$ ./automatic.exe 
Jane is 17 years old
Output of the example.

Anonymous types

The class Person, that we use here is said to be a type. More specifically, it is a user defined type. The type has a name and we can explicitly create an instance of it by referring to its name. Anonymous types are types, that do not have a name. They are class types that consist of one or more public read-only properties. No other kinds of class members are allowed. Anonymous types are created with the new keyword and object initializer. The compiler will infer the types of the properties itself. It will give the type a name, but it is only used by the compiler; it is not available to the programmer. In fact, at compile type, the compiler generates a type from the anonymous type expression. And at runtime, an object is created out of the type.
using System;


public class CSharpApp
{
static void Main()
{
var p = new {Name="Jane", Age=17};

Console.WriteLine("{0} is {1} years old", p.Name, p.Age);
}
}
An anonymous type example.
var p = new {Name="Jane", Age=17};
An anonymous object initializer declares an anonymous type and returns an instance of that type. We use the var keyword, because we do not know the type.
Console.WriteLine("{0} is {1} years old", p.Name, p.Age);
We access the properties created using the field access notation.
$ ./anonymoustype.exe 
Jane is 17 years old
Output.

Extension methods

Developers often face situations, in which they would like to extend an existing type, but it is not possible. For example, the class is sealed. The extension method is a workaround for such cases. Extension methods are a special kind of a static method, but they are called as if they were instance methods on the extended type. To create an extension method, we need a static class and a static method. When we call our extention method on a class, the compiler does some behind the scenes processing; for us it appears as if we have called the extension method on the object of a type.
It is also possible, and it was a common workaround in the past, to create special utility classes for such methods. These were mostly created as static methods of static classes. Both approaches have their advantages. It is also advised to use extension methods sparingly.
using System;

public static class Util
{
public static string Reverse(this string input)
{
char[] chars = input.ToCharArray();
Array.Reverse(chars);
return new String(chars);
}
}

public class CSharpApp
{
static void Main()
{
string str1 = "Jane";
string str2 = str1.Reverse();

Console.WriteLine(str2);
}
}
In our case, we would like to add a new method for a String class. The String class is a built-in class and it is sealed. No inheritance is possible. This is why we need an extension method.
public static class Util
{
public static string Reverse(this string input)
{
char[] chars = input.ToCharArray();
Array.Reverse(chars);
return new String(chars);
}
}
We have a Reverse() extension method. This method reverses characters of a string variable. The method and its class must be static. The static Reverse() method becomes an extension method, when we put the this modifier as the first parameter of the method.
string str1 = "Jane";
string str2 = str1.Reverse();
We define and initialize a string variable. We call the Reverse() method on this variable. Even though the method is static, we use the instance method call syntax.
$ ./extentionmethods.exe 
enaJ
Output.
This part of the C# tutorial we have talked about new features of the C#
Continue Reading

Input And output in CSharp

Input And output in CSharp

This chapter is dedicated to input & output in C#. The input & output in C# is based on streams.
Streams are objects to work with input/output. A stream is an abstraction of a sequence of bytes, such as a file, an input/output device, an inter-process communication pipe, or a TCP/IP socket. In C#, we have a Stream class, that is an abstract class for all streams. There are additional classes that derive from the Stream class and make the programming a lot easier.

MemoryStream

A MemoryStream is a stream which works with data in a computer memory.
using System;
using System.IO;

public class CSharpApp
{
static void Main() {

try
{
Stream ms = new MemoryStream(6);

ms.WriteByte(9);
ms.WriteByte(11);
ms.WriteByte(6);
ms.WriteByte(8);
ms.WriteByte(3);
ms.WriteByte(7);

ms.Position = 0;

int rs;
rs = ms.ReadByte();

do
{
Console.WriteLine(rs);
rs = ms.ReadByte();
} while (rs != -1);

ms.Close();

} catch (IOException e)
{
Console.WriteLine(e.Message);
}
}
}
We write six numbers to a memory with a MemoryStream. Then we read those numbers and print them to the console.
Stream ms = new MemoryStream(6);
The line creates and initializes a MemoryStream object with a capacity of six bytes.
ms.Position = 0;
We set the position of the cursor in the stream to the beginning using the Position property.
ms.WriteByte(9);
ms.WriteByte(11);
ms.WriteByte(6);
...
The WriteByte() method writes a byte to the current stream at the current position.
do 
{
Console.WriteLine(rs);
rs = ms.ReadByte();
} while (rs != -1);
Here we read all bytes from the stream and print them to the console.
ms.Close();
Finally, we close the stream.
$ ./memory.exe 
9
11
6
8
3
7
Output of the example.

StreamReader & StreamWriter

StreamReader reads characters from a byte stream. It defaults to UTF-8 encoding. StreamWriter writes characters to a stream in a particular encoding.
using System;
using System.IO;

public class CSharpApp
{
static void Main() {

try
{
StreamReader stream = new StreamReader("languages");
Console.WriteLine(stream.ReadToEnd());

stream.Close();
} catch (IOException e)
{
Console.WriteLine("Cannot read file.");
Console.WriteLine(e.Message);
}
}
}
We have a file called languages. We read characters from that file and print them to the console.
StreamReader stream = new StreamReader("languages");
The StreamReader takes a file name as a parameter.
Console.WriteLine(stream.ReadToEnd());
The ReadToEnd() method reads all characters to the end of the stream.
$ cat languages 
Python
Visual Basic
PERL
Java
C
C#
$ ./readfile.exe
Python
Visual Basic
PERL
Java
C
C#
We have a languages file in the current directory. We print all lines of the file to the console.

In the next example, we will be counting lines.
using System;
using System.IO;

public class CSharpApp
{
static void Main() {

int count = 0;

try
{
StreamReader stream = new StreamReader("languages");

while(stream.ReadLine() != null)
{
count++;
}

Console.WriteLine("There are {0} lines", count);

stream.Close();

} catch (IOException e)
{
Console.WriteLine("Cannot read file.");
Console.WriteLine(e.Message);
}
}
}
Counting lines in a file.
while(stream.ReadLine() != null)
{
count++;
}
In the while loop, we read a line from the stream with the ReadLine() method. It returns a line from the stream or null if the end of the input stream is reached.

An example with StreamWriter follows. It is a class used for character output.
using System;
using System.IO;

public class CSharpApp
{
static void Main() {

try
{
MemoryStream ms = new MemoryStream();
StreamWriter swriter = new StreamWriter(ms);

swriter.Write("ZetCode, tutorials for programmers.");
swriter.Flush();

ms.Position = 0;
StreamReader sreader = new StreamReader(ms);
Console.WriteLine(sreader.ReadToEnd());

swriter.Close();
sreader.Close();

} catch (IOException e)
{
Console.WriteLine(e.Message);
}
}
}
In the preceding example, we write characters to the memory.
MemoryStream ms = new MemoryStream();
A MemoryStream is created. It is a stream whose backing store is memory.
StreamWriter swriter = new StreamWriter(ms);
A StreamWriter class takes a memory stream as a parameter. This way, we are going to write characters to memory stream.
swriter.Write("ZetCode, tutorials for programmers.");
swriter.Flush();
We write some text to the writer. The Flush()clears all buffers for the current writer and causes any buffered data to be written to the underlying stream.
ms.Position = 0;
We set the current position within the stream to the beginning.
StreamReader sreader = new StreamReader(ms);
Console.WriteLine(sreader.ReadToEnd());
Now we create an instance of the stream reader and read everything we have previously written.

FileStream

A FileStream class uses a stream on a file on the filesystem. This class can be used to read from files, write to files, open them and close them.
using System;
using System.IO;
using System.Text;

public class CSharpApp
{
static void Main() {

try
{
FileStream fstream = new FileStream("author", FileMode.Append);
byte[] bytes = new UTF8Encoding().GetBytes("Фёдор Михайлович Достоевский");

fstream.Write(bytes, 0, bytes.Length);
fstream.Close();
} catch (IOException e)
{
Console.WriteLine(e.Message);
}
}
}
We write some text in Russian azbuka to the file called author in the current working directory.
using System.Text;
We need the System.Text namespace for the UTF8Encodingclass.
FileStream fstream = new FileStream("author", FileMode.Append);
A FileStream object is created. The second parameter is a mode, in which the file is opened. The append mode opens the file if it exists and seeks to the end of the file, or creates a new file.
byte[] bytes = new UTF8Encoding().GetBytes("Фёдор Михайлович Достоевский");
We create an array of bytes from text in russian azbuka.
fstream.Write(bytes, 0, bytes.Length);
We write the bytes to the file stream.
$ cat author 
Фёдор Михайлович Достоевский
We show the contents of the author file.

XmlTextReader

We can use streams to read xml data. The XmlTextReader is the class to read xml files in C#. The class is forward-only and read-only.
We have the following xml test file.
<?xml version="1.0" encoding="utf-8" ?>
<languages>
<language>Python</language>
<language>Ruby</language>
<language>Javascript</language>
<language>C#</language>
</languages>
using System;
using System.IO;
using System.Xml;

public class CSharpApp
{
static void Main() {

string file = "languages.xml";

try
{
XmlTextReader xreader = new XmlTextReader(file);

xreader.MoveToContent();

while (xreader.Read())
{
switch (xreader.NodeType)
{
case XmlNodeType.Element:
Console.Write(xreader.Name + ": ");
break;
case XmlNodeType.Text:
Console.WriteLine(xreader.Value);
break;
}
}

xreader.Close();

} catch (IOException e)
{
Console.WriteLine("Cannot read file.");
Console.WriteLine(e.Message);
} catch (XmlException e)
{
Console.WriteLine("XML parse error");
Console.WriteLine(e.Message);
}
}
}
This C# program reads data from the previously specified xml file and prints it to the terminal.
using System.Xml;
We import the System.Xml namespace, which contains classes related to Xml reading and writing.
XmlTextReader xreader = new XmlTextReader(file);
An XmlTextReader object is created. It is a reader that provides fast, non-cached, forward-only access to XML data. It takes the file name as a parameter.
xreader.MoveToContent();
The MoveToContent() method moves to the actual content of the xml file.
while (xreader.Read())
This line reads the next node from the stream. The Read() method returns false, if there are no more nodes left.
case XmlNodeType.Element:
Console.Write(xreader.Name + ": ");
break;
case XmlNodeType.Text:
Console.WriteLine(xreader.Value);
break;
Here we print the element name and element text.
} catch (XmlException e)
{
Console.WriteLine("XML parse error");
Console.WriteLine(e.Message);
}
We check for xml parse error.
$ ./readxml.exe 
language: Python
language: Ruby
language: Javascript
language: C#
Output of example.

Files and directories

The .NET framework provides other classes that we can use to work with files and directories.
A File class is a higher level class that has static methods for file creation, deletion, copying, moving and opening. These methods make the job easier.
using System;
using System.IO;

public class CSharpApp
{
static void Main() {

try
{
StreamWriter sw = File.CreateText("cars");

sw.WriteLine("Hummer");
sw.WriteLine("Skoda");
sw.WriteLine("BMW");
sw.WriteLine("Volkswagen");
sw.WriteLine("Volvo");

sw.Close();

} catch (IOException e)
{
Console.WriteLine("IO error");
Console.WriteLine(e.Message);
}
}
}
In the example, we create a cars file and write some car names into it.
StreamWriter sw = File.CreateText("cars");
The CreateText() method creates or opens a file for writing UTF-8 encoded text. It returns a StreamWriter object.
sw.WriteLine("Hummer");
sw.WriteLine("Skoda");
...
We write two lines to the stream.
$ cat cars
Hummer
Skoda
BMW
Volkswagen
Volvo
We have successfully written five car names to a cars file.

using System;
using System.IO;

public class CSharpApp
{
static void Main() {

try
{
if (File.Exists("cars"))
{
Console.WriteLine(File.GetCreationTime("cars"));
Console.WriteLine(File.GetLastWriteTime("cars"));
Console.WriteLine(File.GetLastAccessTime("cars"));
}

File.Copy("cars", "newcars");

} catch (IOException e)
{
Console.WriteLine("IO error");
Console.WriteLine(e.Message);
}
}
}
In the second example, we show other five static methods of the File class.
if (File.Exists("cars"))
The Exists() method determines whether the specified file exists.
Console.WriteLine(File.GetCreationTime("cars"));
Console.WriteLine(File.GetLastWriteTime("cars"));
Console.WriteLine(File.GetLastAccessTime("cars"));
We get creation time, last write time and last access time of the specified file.
File.Copy("cars", "newcars");
The Copy() method copies the file.
$ ./copyfile.exe 
10/16/2010 11:48:54 PM
10/16/2010 11:48:54 PM
10/16/2010 11:48:57 PM
Output of the example on my system.

The System.IO.Directory is a class, which has static methods for creating, moving, and enumerating through directories and subdirectories.
using System;
using System.IO;


public class CSharpApp
{
static void Main() {

try
{
Directory.CreateDirectory("temp");
Directory.CreateDirectory("newdir");
Directory.Move("temp", "temporary");
} catch (IOException e)
{
Console.WriteLine("Cannot create directories");
Console.WriteLine(e.Message);
}
}
}
We will use two methods from the above mentioned object. We create two directories and rename one of the created ones.
Directory.CreateDirectory("temp");
The CreateDirectory() method creates a new directory.
Directory.Move("temp", "temporary");
The Move() method gives a specified directory a new name.

The DirectoryInfo and Directory have methods for creating, moving, and enumerating through directories and subdirectories.
using System;
using System.IO;

public class CSharpApp
{
static void Main() {

try
{
DirectoryInfo dir = new DirectoryInfo("../io");

string[] files = Directory.GetFiles("../io");
DirectoryInfo[] dirs = dir.GetDirectories();

foreach(DirectoryInfo subDir in dirs)
{
Console.WriteLine(subDir.Name);
}

foreach(string fileName in files)
{
Console.WriteLine(fileName);
}

} catch (IOException e)
{
Console.WriteLine(e.Message);
}
}
}
We use the DirectoryInfo class to traverse a specific directory and print its contents.
DirectoryInfo dir = new DirectoryInfo("../io");
We will show the contents of this directory (io).
string[] files = Directory.GetFiles("../io");
We get all files of the io directory using the static GetFiles() method.
DirectoryInfo[] dirs = dir.GetDirectories();
We get all directories.
foreach(DirectoryInfo subDir in dirs)
{
Console.WriteLine(subDir.Name);
}
Here we loop through directories and print their names to the console.
foreach(string fileName in files)
{
Console.WriteLine(fileName);
}
Here we loop through the array of files and print their names to the console.
$ ./showcontents.exe 
newdir
temporary
../io/author
../io/cars
../io/cars.cs
../io/cars.cs~
../io/cars.exe
...
Output of the example.
In this chapter, we have covered Input/Output operations in C#.
Continue Reading

Collections in CSharp

Collections

In this chapter we will deal with C# collections. The .NET framework provides specialized classes for data storage and retrieval. In one of the previous chapters, we have described arrays. Collections are enhancement to the arrays.
There are two distinct collection types in C#. The standard collections, which are found under the System.Collections namespace and the generic collections, under System.Collections.Generic. The generic collections are more flexible and are the preferred way to work with data. The generic collections or generics were introduced in .NET framework 2.0. Generics enhance code reuse, type safety, and performance.
Generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters. This approach, pioneered by Ada in 1983, permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplication. (Wikipedia)

ArrayList

ArrayList is a collection from a standard System.Collections namespace. It is a dynamic array. It provides random access to its elements. An ArrayList automatically expands as data is added. Unlike arrays, an ArrayList can hold data of multiple data types. Elements in the ArrayList are accessed via an integer index. Indexes are zero based. Indexing of elements and insertion and deletion at the end of the ArrayList takes constant time. Inserting or deleting an element in the middle of the dynamic array is more costly. It takes linear time.
using System;
using System.Collections;

public class CSharpApp
{
class Empty
{}

static void Main()
{
ArrayList da = new ArrayList();

da.Add("Visual Basic");
da.Add(344);
da.Add(55);
da.Add(new Empty());
da.Remove(55);

foreach(object el in da)
{
Console.WriteLine(el);
}
}
}
In the above example, we have created an ArrayList collection. We have added some elements to it. They are of various data type, string, int and a class object.
using System.Collections;
In order to work with ArrayList collection, we need to import System.Collections namespace.
ArrayList da = new ArrayList();
An ArrayList collection is created.
da.Add("Visual Basic");
da.Add(344);
da.Add(55);
da.Add(new Empty());
da.Remove(55);
We add five elements to the array with the Add() method.
da.Remove(55);
We remove one element.
foreach(object el in da)
{
Console.WriteLine(el);
}
We iterate through the array and print its elements to the console.
$ ./arraylist.exe 
Visual Basic
344
CSharpApp+Empty
Output.

List

A List is a strongly typed list of objects that can be accessed by index. It can be found under System.Collections.Generic namespace.
using System;
using System.Collections.Generic;

public class CSharpApp
{

static void Main()
{
List<string> langs = new List<string>();

langs.Add("Java");
langs.Add("C#");
langs.Add("C");
langs.Add("C++");
langs.Add("Ruby");
langs.Add("Javascript");

Console.WriteLine(langs.Contains("C#"));

Console.WriteLine(langs[1]);
Console.WriteLine(langs[2]);

langs.Remove("C#");
langs.Remove("C");

Console.WriteLine(langs.Contains("C#"));

langs.Insert(4, "Haskell");

langs.Sort();

foreach(string lang in langs)
{
Console.WriteLine(lang);
}

}
}
In the preceding example, we work with the List collection.
using System.Collections.Generic;
In order to work with the List collection, we need to import the System.Collections.Genericnamespace.
List<string> langs = new List<string>();
A generic dynamic array is created. We specify that we will work with strings with the type specified inside <> characters.
langs.Add("Java");
langs.Add("C#");
langs.Add("C");
...
We add elements to the List using the Add() method.
Console.WriteLine(langs.Contains("C#"));
We check if the List contains a specific string using the Contains() method.
Console.WriteLine(langs[1]);
Console.WriteLine(langs[2]);
We access the second and the third element of the List using the index notation.
langs.Remove("C#");
langs.Remove("C");
We remove two strings from the List.
langs.Insert(4, "Haskell");
We insert a string at a specific location.
langs.Sort();
We sort the elements using the Sort()method.
$ ./list.exe 
True
C#
C
False
C++
Haskell
Java
Javascript
Ruby
Outcome of the example.

LinkedList

LinkedList is a generic doubly linked list in C#. LinkedList only allows sequential access. LinkedList allows for constant-time insertions or removals, but only sequential access of elements. Because linked lists need extra storage for references, they are impractical for lists of small data items such as characters. Unlike dynamic arrays, arbitrary number of items can be added to the linked list (limited by the memory of course) without the need to realocate, which is an expensive operation.
using System;
using System.Collections.Generic;

public class CSharpApp
{

static void Main()
{
LinkedList<int> nums = new LinkedList<int>();

nums.AddLast(23);
nums.AddLast(34);
nums.AddLast(33);
nums.AddLast(11);
nums.AddLast(6);
nums.AddFirst(9);
nums.AddFirst(7);

LinkedListNode<int> node = nums.Find(6);
nums.AddBefore(node, 5);

foreach(int num in nums)
{
Console.WriteLine(num);
}
}
}
This is a LinkedList example with some of its methods.
LinkedList<int> nums = new LinkedList<int>();
This is an integer LinkedList.
nums.AddLast(23);
...
nums.AddFirst(7);
We populate the linked list using the AddLast()and AddFirst() methods.
LinkedListNode<int> node = nums.Find(6);
nums.AddBefore(node, 5);
A LinkedList consists of nodes. We find a specific node and add an element before it.
foreach(int num in nums)
{
Console.WriteLine(num);
}
Printing all elements to the console.

Dictionary

A dictionary, also called an associative array, is a collection of unique keys and a collection of values, where each key is associated with one value. Retrieving and adding values is very fast. Dictionaries take more memory, because for each value there is also a key.
using System;
using System.Collections.Generic;


public class CSharpApp
{
static void Main()
{
Dictionary<string, string> domains = new Dictionary<string, string>();

domains.Add("de", "Germany");
domains.Add("sk", "Slovakia");
domains.Add("us", "United States");
domains.Add("ru", "Russia");
domains.Add("hu", "Hungary");
domains.Add("pl", "Poland");

Console.WriteLine(domains["sk"]);
Console.WriteLine(domains["de"]);

Console.WriteLine("Dictionary has {0} items",
domains.Count);

Console.WriteLine("Keys of the dictionary:");

List<string> keys = new List<string>(domains.Keys);

foreach(string key in keys)
{
Console.WriteLine("{0}", key);
}

Console.WriteLine("Values of the dictionary:");

List<string> vals = new List<string>(domains.Values);

foreach(string val in vals)
{
Console.WriteLine("{0}", val);
}

Console.WriteLine("Keys and values of the dictionary:");


foreach(KeyValuePair<string, string> kvp in domains)
{
Console.WriteLine("Key = {0}, Value = {1}",
kvp.Key, kvp.Value);
}
}
}
We have a dictionary, where we map domain names to their country names.
Dictionary<string, string> domains = new Dictionary<string, string>();
We create a dictionary with string keys and values.
domains.Add("de", "Germany");
domains.Add("sk", "Slovakia");
domains.Add("us", "United States");
...
We add some data to the dictionary. The first string is the key. The second is the value.
Console.WriteLine(domains["sk"]);
Console.WriteLine(domains["de"]);
Here we retrieve two values by their keys.
Console.WriteLine("Dictionary has {0} items",
domains.Count);
We print the number of items by referring to the Count property.
List<string> keys = new List<string>(domains.Keys);

foreach(string key in keys)
{
Console.WriteLine("{0}", key);
}
These lines retrieve all keys from the dictionary.
List<string> vals = new List<string>(domains.Values);

foreach(string val in vals)
{
Console.WriteLine("{0}", val);
}
These lines retrieve all values from the dictionary.
foreach(KeyValuePair<string, string> kvp in domains)
{
Console.WriteLine("Key = {0}, Value = {1}",
kvp.Key, kvp.Value);
}
Finally, we print both keys and values of the dictionary.
$ ./dictionary.exe 
Slovakia
Germany
Dictionary has 6 items
Keys of the dictionary:
de
sk
us
ru
hu
pl
Values of the dictionary:
Germany
Slovakia
United States
Russia
Hungary
Poland
Keys and values of the dictionary:
Key = de, Value = Germany
Key = sk, Value = Slovakia
Key = us, Value = United States
Key = ru, Value = Russia
Key = hu, Value = Hungary
Key = pl, Value = Poland
This is the output of the example.

Queues

A queue is a First-In-First-Out (FIFO) data structure. The first element added to the queue will be the first one to be removed. Queues may be used to process messages as they appear or serve customers as they come. The first customer which comes should be served first.
using System;
using System.Collections.Generic;


public class CSharpApp
{
static void Main()
{
Queue<string> msgs = new Queue<string>();

msgs.Enqueue("Message 1");
msgs.Enqueue("Message 2");
msgs.Enqueue("Message 3");
msgs.Enqueue("Message 4");
msgs.Enqueue("Message 5");

Console.WriteLine(msgs.Dequeue());
Console.WriteLine(msgs.Peek());
Console.WriteLine(msgs.Peek());

Console.WriteLine();

foreach(string msg in msgs)
{
Console.WriteLine(msg);
}
}
}
In our example, we have a queue with messages.
Queue<string> msgs = new Queue<string>();
A queue of strings is created.
msgs.Enqueue("Message 1");
msgs.Enqueue("Message 2");
...
The Enqueue() adds a message to the end of the queue.
Console.WriteLine(msgs.Dequeue());
The Dequeue() method removes and returns the item at the beginning of the queue.
Console.WriteLine(msgs.Peek());
The Peek() method returns the next item from the queue, but does not remove it from the collection.
$ ./queue.exe 
Message 1
Message 2
Message 2

Message 2
Message 3
Message 4
Message 5
The Dequeue() method removes the "Message 1" from the collection. The Peek() method does not. The "Message 2" remains in the collection.

Stacks

A stack is a Last-In-First-Out (LIFO) data structure. The last element added to the queue will be the first one to be removed. The C language uses a stack to store local data in a function. The stack is also used when implementing calculators.
using System;
using System.Collections.Generic;


public class CSharpApp
{
static void Main()
{
Stack<int> stc = new Stack<int>();

stc.Push(1);
stc.Push(4);
stc.Push(3);
stc.Push(6);
stc.Push(4);

Console.WriteLine(stc.Pop());
Console.WriteLine(stc.Peek());
Console.WriteLine(stc.Peek());

Console.WriteLine();

foreach(int item in stc)
{
Console.WriteLine(item);
}
}
}
We have a simple stack example above.
Stack<int> stc = new Stack<int>();
A Stack data structure is created.
stc.Push(1);
stc.Push(4);
...
The Push() method adds an item at the top of the stack.
Console.WriteLine(stc.Pop());
The Pop() method removes and returns the item from the top of the stack.
Console.WriteLine(stc.Peek());
The Peek() method returns the item from the top of the stack. It does not remove it.
$ ./stack.exe 
4
6
6

6
3
4
1
Output.
This part of the C# tutorial was dedicated to Collections in C#.


Continue Reading

Namespaces in CSharp

Namespaces

In this part of the C# tutorial, we will describe namespaces.
Namespaces are used to organize code at the highest logical level. They classify and present programming elements that are exposed to other programs and applications. Within a namespace, we can declare another namespace, a class, an interface, a struct, an enum or a delegate. We cannot define items such as properties, variables and events. These items must be declared within containers such as structures or classes. Namespaces prevent ambiguity and simplify references when using large groups of objects such as class libraries.
Namespaces organize objects in an assembly. An assembly is a reusable, versionable and self-describing building block of a CLR application. Assemblies can contain multiple namespaces. Namespaces can contain other namespaces. An assembly provides a fundamental unit of physical code grouping. A namespace provides a fundamental unit of logical code grouping.
public class CSharpApp
{
static void Main()
{
System.Console.WriteLine("Simple namespace example");
}
}
The built-in libraries are organized within namespaces. Take the Console class. It is available within the System namespace. To call the static WriteLine() method of the Console class, we use its fully qualified name. Fully qualified names are object references that are prefixed with the name of the namespace where the object is defined.

In the following code, we have two files that share the same namespace.
using System;

// namespace2.cs

namespace ZetCode
{
public class Example
{
public int x = 0;

public void Raise()
{
x += 100;
Console.WriteLine(x);
}
}
}
We have a ZetCode namespace. In the namespace, we have a class Example.
namespace ZetCode
{
...
}
We declare a namespace called ZetCode. The code goes inside the curly brackets of the ZetCode namespace.
// namespace1.cs

namespace ZetCode
{
public class CSharpApp
{
static void Main()
{
Example ex = new Example();
ex.Raise();
ex.Raise();
}
}
}
In the second file, we work with the Example class from the previous file. We invoke its Raise() method
namespace ZetCode
We work in the same namespace.
Example ex = new Example();
ex.Raise();
ex.Raise();
We create the instance of the Example class. We call its Raise() method twice. Because we work with objects of the same namespace, we do not need to specify its name.
$ gmcs namespace1.cs namespace2.cs
$ ./namespace1.exe
100
200
Output.

The following code example has two distinct namespaces. We use the using keyword to import elements from a different namespace.
// distinctnamespace2.cs

namespace MyMath
{
public class Basic
{
public static double PI = 3.141592653589;

public static double GetPi()
{
return PI;
}
}
}
We have a skeleton of a Math class in a MyMath namespace. In the Basic class, we define a PI constant and a GetPi() method.
// distinctnamespace1.cs

using MyMath;
using System;

namespace ZetCode
{
public class CSharpApp
{
static void Main()
{
Console.WriteLine(Basic.PI);
Console.WriteLine(Basic.GetPi());
}
}
}
In this file, we use the elements from the MyMath namespace.
using MyMath;
We import the elements from the MyMath namespace into our namespace.
Console.WriteLine(Basic.PI)
Console.WriteLine(Basic.GetPI())
Now we can use those elements. In our case it is the Basic class.
$ gmcs distinctnamespace1.cs distinctnamespace2.cs
$ ./distinctnamespace1.exe
3.141592653589
3.141592653589
We compile the two files and run the program.
This part of the C# tutorial was dedicated to namespaces.
Continue Reading

Delegates in CSharp

Delegates

This part of the C# tutorial is dedicated to delegates.
Delegate A delegate is a form of type-safe function pointer used by the .NET Framework. Delegates are often used to implement callbacks and event listeners. A delegate does not need to know anything about classes of methods it works with.
A delegate is a reference type. But instead of referring to an object, a delegate refers to a method.
Delegates are used in the following cases:
  • Event handlers
  • Callbacks
  • LINQ
  • Implementation of design patterns
There is nothing that is done with delegates that cannot be done with regular methods. Delegates are used, because they bring several advantages. They foster flexibility of the application and code reuse. Like interfaces, delegates let us decouple and generalize our code. Delegates also allow methods to be passed as parameters. When we need to decide which method to call at runtime, we use a delegate. Finally, delegates provide a way of specializing behavior of a class without subclassing it. Classes may have complex generic behavior, but are still meant to be specialized. Classes are specialized either through inheritance or via delegates.

Using delegates

Simple delegates We will have some simple examples showing, how to use delegates.
using System;   


delegate void Mdelegate();

public class CSharpApp
{
static void Main()
{
Mdelegate del = new Mdelegate(Callback);
del();
}

static void Callback()
{
Console.WriteLine("Calling callback");
}
}
We declare a delegate, create an instance of the delegate and invoke it.
delegate void Mdelegate();
This is our delegate declaration. It returns no value and takes no parameters.
Mdelegate del = new Mdelegate(Callback);
We create an instance of the delegate. When called, the delegate will invoke the static Callback() method.
del();
We call the delegate.
$ ./simple.exe 
Calling callback
Output.

Simplified syntax We can use a different syntax for creating and using a delegate.
using System;   


delegate void Mdelegate();

public class CSharpApp
{
static void Main()
{
Mdelegate del = Callback;
del();
}

static void Callback()
{
Console.WriteLine("Calling callback");
}
}
We can save some typing when creating an instance of a delegate. It was introduces in C# 2.0.
Mdelegate del = Callback;
This is another way of creating a delegate. We save some typing.

Anonymous methods It is possible to use anonymous methods with delegates.
using System;   


delegate void Mdelegate();

public class CSharpApp
{
static void Main()
{
Mdelegate del = delegate {
Console.WriteLine("Anonymous method");
};

del();
}
}
We can omit a method declaration when using an anonymous method with a delegate. The method has no name and can be invoked only via the delegate.
Mdelegate del = delegate { 
Console.WriteLine("Anonymous method");
};
Here we create a delegate, that points to an anonymous method. The anonymous method has a body enclosed by { } characters, but it has no name.

A delegate can point to different methods over time.
using System;


public delegate void NameDelegate(string msg);

public class Person
{
public string firstName;
public string secondName;

public Person(string firstName, string secondName)
{
this.firstName = firstName;
this.secondName = secondName;
}

public void ShowFirstName(string msg)
{
Console.WriteLine(msg + this.firstName);
}

public void ShowSecondName(string msg)
{
Console.WriteLine(msg + this.secondName);
}
}

public class CSharpApp
{
public static void Main()
{
Person per = new Person("Fabius", "Maximus");

NameDelegate nDelegate = new NameDelegate(per.ShowFirstName);
nDelegate("Call 1: ");

nDelegate = new NameDelegate(per.ShowSecondName);
nDelegate("Call 2: ");
}
}
In the example we have one delegate. This delegate is used to point to two methods of the Person class. The methods are called with the delegate.
public delegate void NameDelegate(string msg);
The delegate is created with a delegate keyword. The delegate signature must match the signature of the method being called with the delegate.
NameDelegate nDelegate = new NameDelegate(per.ShowFirstName);
nDelegate("Call 1: ");
We create an instance of a new delegate, that points to the ShowFirstName() method. Later we call the method via the delegate.
$ ./simpledelegate.exe 
Call 1: Fabius
Call 2: Maximus
Both names are printed via the delegate.

Multicast delegate Multicast delegate is a delegate which holds a reference to more than one method. Multicast delegates must contain only methods that return void, else there is a run-time exception.
using System;   


delegate void Mdelegate(int x, int y);

public class Oper
{
public static void Add(int x, int y)
{
Console.WriteLine("{0} + {1} = {2}", x, y, x + y);
}

public static void Sub(int x, int y)
{
Console.WriteLine("{0} - {1} = {2}", x, y, x - y);
}
}

public class CSharpApp
{
static void Main()
{
Mdelegate del = new Mdelegate(Oper.Add);

del += new Mdelegate(Oper.Sub);
del(6, 4);
del -= new Mdelegate(Oper.Sub);
del(2, 8);
}
}
This is an example of a multicast delegate.
delegate void Mdelegate(int x, int y);
Our delegate will take two parameters. We have an Oper class, which has two static methods. One adds two values the other one subtracts two values.
Mdelegate del = new Mdelegate(Oper.Add);
We create an instance of our delegate. The delegate points to the static Add() method of the Oper class.
del += new Mdelegate(Oper.Sub);
del(6, 4);
We plug another method to the existing delegate instance. The first call of the delegate invokes two methods.
del -= new Mdelegate(Oper.Sub);
del(2, 8);
We remove one method from the delegate. The second call of the delegate invokes only one method.
$ ./multicast.exe 
6 + 4 = 10
6 - 4 = 2
2 + 8 = 10
Output.

Delegates as method parameters

Delegates can be used as method parameters.
using System;   


delegate int Arithm(int x, int y);

public class CSharpApp
{
static void Main()
{
DoOperation(10, 2, Multiply);
DoOperation(10, 2, Divide);
}

static void DoOperation(int x, int y, Arithm del)
{
int z = del(x, y);
Console.WriteLine(z);
}

static int Multiply(int x, int y)
{
return x * y;
}

static int Divide(int x, int y)
{
return x / y;
}
}
We have a DoOperation() method, which takes a delegate as a parameter.
delegate int Arithm(int x, int y);
This is a delegate declaration.
static void DoOperation(int x, int y, Arithm del)
{
int z = del(x, y);
Console.WriteLine(z);
}
This is DoOperation() method implementation. The third parameter is a delegate. The DoOperation() method calls a method, which is passed to it as a third parameter.
DoOperation(10, 2, Multiply);
DoOperation(10, 2, Divide);
We call the DoOperation() method. We pass two values and a method to it. What we do with the two values, depends on the method that we pass. This is the flexibility that come with using delegates.

Events

Events are messages triggered by some action. Click on the button or tick of a clock are such actions. The object that triggers an event is called a sender and the object that receives the event is called a receiver.
By convention, event delegates in the .NET Framework have two parameters, the source that raised the event and the data for the event.
using System;   


public delegate void OnFiveHandler(object sender, EventArgs e);

class FEvent {
public event OnFiveHandler FiveEvent;

public void OnFiveEvent()
{
if(FiveEvent != null)
FiveEvent(this, EventArgs.Empty);
}
}

public class CSharpApp
{
static void Main()
{
FEvent fe = new FEvent();
fe.FiveEvent += new OnFiveHandler(Callback);

Random random = new Random();

for (int i = 0; i<10; i++)
{
int rn = random.Next(6);

Console.WriteLine(rn);

if (rn == 5)
{
fe.OnFiveEvent();
}
}
}

public static void Callback(object sender, EventArgs e)
{
Console.WriteLine("Five Event occured");
}
}
We have a simple example in which we create and launch an event. An random number is generated. If the number equals to 5 a FiveEvent event is generated.
public event OnFiveHandler FiveEvent;
An event is declared with a event keyword.
fe.FiveEvent += new OnFiveHandler(Callback);
Here we plug the event called FiveEvent to the Callback method. In other words, if the ValueFive event is triggered, the Callback() method is executed.
public void OnFiveEvent() 
{
if(FiveEvent != null)
FiveEvent(this, EventArgs.Empty);
}
When the random number equals to 5, we invoke the OnFiveEvent() method. In this method, we raise the FiveEvent event. This event carries no arguments.
$ ./simpleevent.exe 
3
0
5
Five Event occured
0
5
Five Event occured
2
3
4
4
0
Outcome of the program might look like this.

Complex event example Next we have a more complex example. This time we will send some data with the generated event.
using System;   


public delegate void OnFiveHandler(object sender, FiveEventArgs e);

public class FiveEventArgs : EventArgs
{
public int count;
public DateTime time;

public FiveEventArgs(int count, DateTime time)
{
this.count = count;
this.time = time;
}
}

public class FEvent
{
public event OnFiveHandler FiveEvent;

public void OnFiveEvent(FiveEventArgs e)
{
FiveEvent(this, e);
}
}

public class RandomEventGenerator
{
public void Generate()
{
int count = 0;
FiveEventArgs args;

FEvent fe = new FEvent();
fe.FiveEvent += new OnFiveHandler(Callback);

Random random = new Random();

for (int i = 0; i<10; i++)
{
int rn = random.Next(6);

Console.WriteLine(rn);

if (rn == 5)
{
count++;
args = new FiveEventArgs(count, DateTime.Now);
fe.OnFiveEvent(args);
}
}
}

public void Callback(object sender, FiveEventArgs e)
{
Console.WriteLine("Five event {0} occured at {1}",
e.count, e.time);
}
}

public class CSharpApp
{
static void Main()
{
RandomEventGenerator reg = new RandomEventGenerator();
reg.Generate();
}
}
We have four classes. FiveEventArgs carries some data with the event object. The FEvent class encapsulates the event object. RandomEventGenerator class is responsible for random number generation. It is the event sender. Finally the CSharpApp class, which is the main application object and has the Main() method.
public class FiveEventArgs : EventArgs
{
public int count;
public DateTime time;
...
The FiveEventArgs carries data inside the event object. It inherits from the EventArgs base class. The count and time members are data that will be initialized and carried with the event.
if (rn == 5)
{
count++;
args = new FiveEventArgs(count, DateTime.Now);
fe.OnFiveEvent(args);
}
If the generated random number equals to 5, we instantiate the FiveEventArgs class with the current count and DateTime values. The count variable counts the number of times this event was generated. The DateTime value holds the time, when the event was generated.
$ ./complexevent.exe 
2
2
3
5
Five event 1 occured at 11/7/2010 12:13:59 AM
5
Five event 2 occured at 11/7/2010 12:13:59 AM
1
1
0
5
Five event 3 occured at 11/7/2010 12:13:59 AM
5
Five event 4 occured at 11/7/2010 12:13:59 AM
This is the ouput I got on my computer.

Predefined delegates

The .NET framework has several built-in delegates that a reduce the typing needed and make the programming easier for developers.
Action delegate An action delegate encapsulates a method that has no parameters and does not return a value.
using System;   

public class CSharpApp
{
static void Main()
{
Action act = ShowMessage;
act();
}

static void ShowMessage()
{
Console.WriteLine("C# language");
}
}
Using predefined delegates further simplifies programming. We do not need to declare a delegate type.
Action act = ShowMessage;
act();
We instantiate an action delegate. The delegate points to the ShowMessage() method. When the delegate is invoked, the ShowMessage() method is executed.

Action<T> delegate There are multiple types of action delegates. For example, the Action<T> delegate encapsulates a method that takes a single parameter and does not return a value.
using System;   

public class CSharpApp
{
static void Main()
{
Action<string> act = ShowMessage;
act("C# language");
}

static void ShowMessage(string message)
{
Console.WriteLine(message);
}
}
We modify the previous example to use the action delegate, that takes one parameter.
Action<string> act = ShowMessage;
act("C# language");
We create an instance of the Action<T> delegate and call it with one parameter.

Predicate delegate A predicate is a method that returns true or false. A predicate delegate is a reference to a predicate. Predicates are very useful for filtering a list of values.
using System;
using System.Collections.Generic;

public class CSharpApp
{
static void Main()
{
List<int> list = new List<int> { 4, 2, 3, 0, 6, 7, 1, 9 };

Predicate<int> predicate = greaterThanThree;

List<int> list2 = list.FindAll(predicate);

foreach ( int i in list2)
{
Console.WriteLine(i);
}
}

static bool greaterThanThree(int x)
{
return x > 3;
}
}
We have a list of integer values. We want to filter all numbers, that are bigger than three. For this, we use the predicate delegate.
List<int> list = new List<int> { 4, 2, 3, 0, 6, 7, 1, 9 };
This is a generic list of integer values.
Predicate<int> predicate = greaterThanThree;
We create an instance of a predicate delegate. The delegate points to a predicate, a special method that returns true or false.
List<int> list2 = list.FindAll(predicate);
The FindAll() method retrieves all the elements that match the conditions defined by the specified predicate.
static bool greaterThanThree(int x)
{
return x > 3;
}
The predicate returns true for all values, that are greater than three.
This part of the C# tutorial was dedicated to the delegates.
Continue Reading

Structures in CSharp

Structures

In this part of the C# tutorial, we will cover structures.
A structure is a value type. The type is defined with the struct keyword. Structures are very similar to the classes; they differ in some aspects. Structures are meant to represent lightweight objects like Point, Rectangle, Color and similar. In many cases, structures may be more efficient than classes. Structures are value types and are created on the stack. Note that primitive data types like int, bool, float are technically struct types.
Structures can have constructors. They can contain data members and methods. They also can implement interfaces.
All struct types inherit from System.ValueType. And further from object. Structures are never abstract and they are always implicitly sealed. So struct types do not support inheritance. And therefore, the struct data member cannot be declared protected. The abstract and sealed modifiers are not permitted for a struct definition. A struct is not permitted to declare a parameterless constructor.
using System;


public struct Point
{
private int x;
private int y;

public Point(int x, int y)
{
this.x = x;
this.y = y;
}

public override string ToString()
{
return String.Format("Point, x:{0}, y:{1}", x, y);
}
}


public class CSharpApp
{
static void Main()
{
Point p = new Point(2, 5);
Console.WriteLine(p);
}
}
We have a simple example demonstrating the struct type. We create a Point struct. The point could be represented by a class too, but with struct we are more efficient. Especially if we dealt with lots of points.
public struct Point
{
...
}
The structure is declared with the struct keyword.
public override string ToString()
{
return String.Format("Point, x:{0}, y:{1}", x, y);
}
The inheritance is not supported for struct types. But we can use the override keyword for methods, from which the struct type implicitly inherits. The ToString() method is such a case.
Point p = new Point(2, 5);
Console.WriteLine(p);
We create the Point structure and call the ToString() method upon it.
$ ./simple.exe 
Point, x:2, y:5
Output.

It is possible to create an instance of the struct type without the new keyword.
using System;


public struct Person
{
public string name;
public int age;
}

public class CSharpApp
{
static void Main()
{
Person p;
p.name = "Jane";
p.age = 17;

Console.WriteLine("{0} is {1} years old",
p.name, p.age);
}
}
We have a Person structure with two public members.
Person p;
First we declare a Person struct.
p.name = "Jane";
p.age = 17;
Later we initialize the structure with some data.
$ ./properties.exe 
Jane is 17 years old
Output.

Structures are value types The structure types are value types. They are created on the stack. When a value type is created only a single space in memory is allocated to store the value. An assignment of a value type copies the value.
using System;


public struct Person
{
public Person(string name, int age)
{
this.Name = name;
this.Age = age;
}

public string Name { get; set; }

public int Age { get; set; }

public override string ToString()
{
return String.Format("{0} is {1} years old", Name, Age);
}
}


public class CSharpApp
{
static void Main()
{
Person p1 = new Person("Beky", 18);
Person p2 = p1;

Console.WriteLine(p2);
p2.Name = "Jane";
p2.Age = 17;

Console.WriteLine(p2);
Console.WriteLine(p1);
}
}
We have a Person structure with two data members. We have a two parameter constructor and we also use automatic properties.
public string Name { get; set; }
public int Age { get; set; }
Automatic properties can be used in struct types.
Person p1 = new Person("Beky", 18);
Person p2 = p1;
Here we create a struct. And then the created struct is assigned to another struct. We create a copy of the structure.
p2.Name = "Jane";
p2.Age = 17;
We change the data of the second structure. The first one is not affected, since we work on the copy of the original struct type.
$ ./valuetype.exe 
Beky is 18 years old
Jane is 17 years old
Beky is 18 years old
Output.

Primitive types are structures The primitive data types like int, float or bool are structures under the hood. This differs from languages like C++ or Java. We will have an example demonstrating this.
using System;


public class CSharpApp
{
static void Main()
{
float x = 12.3f;
int y = 34;
bool z = false;

Console.WriteLine(x.GetType());
Console.WriteLine(y.GetType());
Console.WriteLine(z.GetType());
}
}
We have three variables. A float an int and a bool. We call the GetType() method on each of them.
Console.WriteLine(x.GetType());
We call the GetType() method on the float value. Each structure implicitly inherits from the System.ValueType class, which contains the GetType() method.
$ ./primitivetypes.exe 
System.Single
System.Int32
System.Boolean
Output.
In this part of the C# tutorial, we mentioned structures.
Continue Reading

Properties in CSharp

Properties

In this part of the C# tutorial, we will talk about properties.
Properties are special kind of class members. We use predefined set and get methods to access and modify them. Property reads and writes are translated to get and set method calls. Accessing variables with a field notation (e.g. object.Name) is easier than with custom method calls.(e.g. object.GetName()). However with properties, we still have the advantage of encapsulation and information hiding. In other words, properties shield the data from the outside world while having a convenient field access.
using System;


public class Person
{
private string _name;

public string Name
{
get { return _name; }
set { _name = value;}
}
}

public class CSharpApp
{
static void Main()
{
Person p = new Person();
p.Name = "Jane";

Console.WriteLine(p.Name);
}
}
We have a simple Person class with one property.
public string Name
{
...
}
We have a property that is called Name. It looks like a regular method declaration. The difference is that it has specific accessors called get and set.
get { return _name; }
set { _name = value; }
A get property accessor is used to return the property value, and a set accessor is used to assign a new value. The value keyword is used to define the value being assigned by the set indexer.
Person p = new Person();
p.Name = "Jane";

Console.WriteLine(p.Name);
We create an instance of the Person class. We access the member field using the field notation.
$ ./properties.exe 
Jane
This is the outcome of the program.

Read-only properties

It is possible to create read-only properties. To create a read-only property, we omit the set accessor and provide only the get accessor in the implementation.
using System;


public class Person
{
private string _name = "Jane";

public string Name
{
get { return _name; }
}
}

public class CSharpApp
{
static void Main()
{
Person p = new Person();
// p.Name = "Jane";

Console.WriteLine(p.Name);
}
}
In the preceding example, we demonstrate the use of a read-only property.
private string _name = "Jane";
We initialize the member right away, because later it is not possible.
public string Name
{
get { return _name; }
}
We make the property read-only by providing a get accessor only.
// p.Name = "Jane";
This line is now commmented. We cannot change the property. If we uncommented the line, the Mono C# compiler would issue the following error: readonly.cs(19,11): error CS0200: Property or indexer `Person.Name' cannot be assigned to (it is read-only).

Automatic properties

C# version 3.0 introduced auto-implemented or automatic properties. In a software project, there are lots of simple properties, that only set or get some simple values. To simplify programmming and to make the code shorter, automatic properties were created. Note that we cannot use automatic properties in all cases. Only for the simple ones.
using System;


public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}

public class CSharpApp
{
public static void Main()
{
Person p = new Person();
p.Name = "Jane";
p.Age = 17;

Console.WriteLine("{0} is {1} years old",
p.Name, p.Age);
}
}
This code is much shorter. We have a person class in which we have two properties.
public string Name { get; set; }
public int Age { get; set; }
Here we have two automatic properties. There is no implementation of the accessors. And there are no member fields. The compiler will do the rest for us.
Person p = new Person();
p.Name = "Jane";
p.Age = 17;

Console.WriteLine("{0} is {1} years old",
p.Name, p.Age);
We normally use the properties as usual.
$ ./automatic.exe 
Jane is 17 years old
Output of the example.

Other notes

We can mark properties with access modifiers like public, private or protected. Properties can be static also. C# supports also abstract, virtual and sealed properties. They are used similarly like for regular methods.
using System;


public class Base
{
protected string _name = "Base class";

public virtual string Name
{
set { _name = value; }
get { return _name; }
}
}

public class Derived : Base
{
protected new string _name = "Derived class";

public override string Name
{
set { _name = value; }
get { return _name; }
}
}

public class CSharpApp
{
public static void Main()
{
Base b = new Base();
Derived d = new Derived();

Console.WriteLine(b.Name);
Console.WriteLine(d.Name);
}
}
In the preceding example, we define a virtual property and override it in the Derived class.
public virtual string Name
{
set { _name = value; }
get { return _name; }
}
The Name property is marked with the virtual keyword.
protected new string _name = "Derived class"; 
We are hiding a member in the Derived class. To supress the compiler warning, we use the new keyword.
public override string Name
{
set { _name = value; }
get { return _name; }
}
And here we override the Name property of the Base class.
This chapter covered C# properties. We described the properties and showed, how they are implemented. We mentioned automatic properties and read-only properties.
Continue Reading

CSharp Object-oriented programming

Object-oriented programming II

In this chapter of the C# tutorial, we continue description of the OOP.

Interfaces

A remote control is an interface between the viewer and the TV. It is an interface to this electronic device. Diplomatic protocol guides all activities in the diplomatic field. Rules of the road are rules that motorists, cyclists and pedestrians must follow. Interfaces in programming are analogous to the previous examples.
Interfaces are:
  • APIs
  • Contracts
Objects interact with the outside world with the methods, they expose. The actual implementation is not important to the programmer, or it also might be secret. A company might sell a library and it does not want to disclose the actual implementation. A programmer might call a Maximize() method on a window of a GUI toolkit, but knows nothing about how this method is implemented. From this point of view, interfaces are methods, through which objects interact with the outside world, without exposing too much about their inner workings.
From the second point of view, interfaces are contracts. If agreed upon, they must be followed. They are used to design an architecture of an application. They help organize the code.
Interfaces are fully abstract types. They are declared using the interface keyword. Interfaces can only have signatures of methods, properties, events or indexers. All interface members implicitly have public access. Interface members cannot have access modifiers specified. Interfaces cannot have fully implemented methods, nor member fields. A C# class may implement any number of interfaces. A n interface can also extend any number of interfaces. A class that implements an interface must implement all method signatures of an interface.
Interfaces are used to simulate multiple inheritance. A C# class can inherit only from one class. A C# class can implement multiple interfaces. Multiple inheritance using the interfaces is not about inheriting methods and variables. It is about inheriting ideas or contracts, which are described by the interfaces.
There is one important distinction between interfaces and abstract classes. Abstract classes provide partial implementation for classes, that are related in the inheritance hierarchy. Interfaces on the other hand can be implemented by classes, that are not related to each other. For example, we have two buttons. A classic button and a round button. Both inherit from an abstract button class, that provides some common functionality to all buttons. Implementing classes are related, since all are buttons. Another example might have classes Database and SignIn. They are not related to each other. We can apply an ILoggable interface, that would force them to create a method to do logging.
using System;


public interface IInfo
{
void DoInform();
}

public class Some : IInfo
{
public void DoInform()
{
Console.WriteLine("This is Some Class");
}
}

public class CSharpApp
{

static void Main()
{
Some sm = new Some();
sm.DoInform();
}
}
This is a simple C# program demonstrating an interface.
public interface IInfo
{
void DoInform();
}
This is an interface IInfo. It has the DoInform()method signature.
public class Some : IInfo
We implement the IInfo interface. To implement a specific interface, we use the colon (:) operator.
public void DoInform()
{
Console.WriteLine("This is Some Class");
}
The class provides an implementation for the DoInform()method.

The next example shows, how a class can implement multiple interfaces.
using System;


public interface Device
{
void SwitchOn();
void SwitchOff();
}

public interface Volume
{
void VolumeUp();
void VolumeDown();
}

public interface Pluggable
{
void PlugIn();
void PlugOff();
}

public class CellPhone : Device, Volume, Pluggable
{
public void SwitchOn()
{
Console.WriteLine("Switching on");
}

public void SwitchOff()
{
Console.WriteLine("Switching on");
}

public void VolumeUp()
{
Console.WriteLine("Volume up");
}

public void VolumeDown()
{
Console.WriteLine("Volume down");
}

public void PlugIn()
{
Console.WriteLine("Plugging In");
}

public void PlugOff()
{
Console.WriteLine("Plugging Off");
}
}

public class CSharpApp
{
static void Main()
{
CellPhone cp = new CellPhone();
cp.SwitchOn();
cp.VolumeUp();
cp.PlugIn();
}
}
We have a CellPhone class that inherits from three interfaces.
public class CellPhone : Device, Volume, Pluggable
The class implements all three interfaces, which are divided by a comma. The CellPhone class must implement all method signatures from all three interfaces.
$ ./interface2.exe 
Switching on
Volume up
Plugging In
Running the program.

The next example shows how interfaces can inherit from multiple other interfaces.
using System;


public interface IInfo
{
void DoInform();
}

public interface IVersion
{
void GetVersion();
}

public interface ILog : IInfo, IVersion
{
void DoLog();
}

public class DBConnect : ILog
{

public void DoInform()
{
Console.WriteLine("This is DBConnect class");
}

public void GetVersion()
{
Console.WriteLine("Version 1.02");
}

public void DoLog()
{
Console.WriteLine("Logging");
}

public void Connect()
{
Console.WriteLine("Connecting to the database");
}
}

public class CSharpApp
{
static void Main()
{
DBConnect db = new DBConnect();
db.DoInform();
db.GetVersion();
db.DoLog();
db.Connect();
}
}
We define three interfaces. We can organize interfaces in a hierarchy.
public interface ILog : IInfo, IVersion
The ILog interface inherits from two other interfaces.
public void DoInform() 
{
Console.WriteLine("This is DBConnect class");
}
The DBConnect class implements the DoInform() method. This method was inherited by the ILog interface, which the class implements.
$ ./interface3.exe 
This is DBConnect class
Version 1.02
Logging
Connecting to the database
Output.

Polymorphism

The polymorphism is the process of using an operator or function in different ways for different data input. In practical terms, polymorphism means that if class B inherits from class A, it doesn't have to inherit everything about class A; it can do some of the things that class A does differently. (wikipedia)
In general, polymorphism is the ability to appear in different forms. Technically, it is the ability to redefine methods for derived classes. Polymorphism is concerned with the application of specific implementations to an interface or a more generic base class.
Polymorphism is the ability to redefine methods for derived classes.
using System;

public abstract class Shape
{
protected int x;
protected int y;

public abstract int Area();
}

public class Rectangle : Shape
{
public Rectangle(int x, int y)
{
this.x = x;
this.y = y;
}

public override int Area()
{
return this.x * this.y;
}
}

public class Square : Shape
{
public Square(int x)
{
this.x = x;
}

public override int Area()
{
return this.x * this.x;
}
}

public class CSharpApp
{
static void Main()
{
Shape[] shapes = { new Square(5),
new Rectangle(9, 4), new Square(12) };

foreach (Shape shape in shapes)
{
Console.WriteLine(shape.Area());
}
}
}
In the above program, we have an abstract Shape class. This class morphs into two descendant classes, Rectangle and Square. Both provide their own implementation of the Area() method. Polymorphism brings flexibility and scalability to the OOP systems.
public override int Area()
{
return this.x * this.y;
}
...
public override int Area()
{
return this.x * this.x;
}
Rectangle and Square classes have their own implementations of the Area() method.
Shape[] shapes = { new Square(5), 
new Rectangle(9, 4), new Square(12) };
We create an array of three Shapes.
foreach (Shape shape in shapes)
{
Console.WriteLine(shape.Area());
}
We go through each shape and call Area() method on it. The compiler calls the correct method for each shape. This is the essence of polymorphism.

Sealed classes

The sealed keyword is used to prevent unintended derivation from a class. A sealed class cannot be an abstract class.
using System;

sealed class Math
{
public static double GetPI()
{
return 3.141592;
}
}

public class Derived : Math
{

public void Say()
{
Console.WriteLine("Derived class");
}
}

public class CSharpApp
{
static void Main()
{
DerivedMath dm = new DerivedMath();
dm.Say();
}
}
In the above program, we have a base Math class. The sole purpose of this class is to provide some helpful methods and constants to the programmer. (In our case we have only one method for simplicity reasons.) It is not created to be inherited from. To prevent uninformed other programmers to derive from this class, the creators made the class sealed. If you try to compile this program, you get the following error: 'DerivedMath' cannot derive from sealed class `Math'.

Deep copy vs shallow copy

Copying of data is an important task in programming. Object is a composite data type in OOP. Member field in an object may be stored by value or by reference. Copying may be performed in two ways.
The shallow copy copies all values and references into a new instance. The data to which a reference is pointing is not copied; only the pointer is copied. The new references are pointing to the original objects. Any changes to the reference members affect both objects.
The deep copy copies all values into a new instance. In case of members that are stored as references a deep copy performs a deep copy of data, that is being referenced. A new copy of a referenced object is created. And the pointer to the newly created object is stored. Any changes to those referenced objects will not affect other copies of the object. Deep copies are fully replicated objects.
If a member field is a value type, a bit-by-bit copy of the field is performed. If the field is a reference type, the reference is copied but the referred object is not; therefore, the reference in the original object and the reference in the clone point to the same object. (a clear explanation from programmingcorner.blogspot.com)
The next two examples will perform a shallow and a deep copy on objects.
using System;


public class Color
{
public int red;
public int green;
public int blue;

public Color(int red, int green, int blue)
{
this.red = red;
this.green = green;
this.blue = blue;
}
}

public class MyObject : ICloneable
{
public int id;
public string size;
public Color col;

public MyObject(int id, string size, Color col)
{
this.id = id;
this.size = size;
this.col = col;
}

public object Clone()
{
return new MyObject(this.id, this.size, this.col);
}

public override string ToString()
{
string s;
s = String.Format("id: {0}, size: {1}, color:({2}, {3}, {4})",
this.id, this.size, this.col.red, this.col.green, this.col.blue);
return s;
}
}

public class CSharpApp
{
static void Main()
{
Color col = new Color(23, 42, 223);
MyObject obj1 = new MyObject(23, "small", col);

MyObject obj2 = (MyObject) obj1.Clone();

obj2.id += 1;
obj2.size = "big";
obj2.col.red = 255;

Console.WriteLine(obj1);
Console.WriteLine(obj2);
}
}
This is an example of a shallow copy. We define two custom objects. MyObject and Color. The MyObject object will have a reference to the Color object.
public class MyObject : ICloneable
We should implement ICloneable interface for objects, which we are going to clone.
public object Clone()
{
return new MyObject(this.id, this.size, this.col);
}
The ICloneable interface forces us to create a Clone() method. This method returns a new object with copied values.
Color col = new Color(23, 42, 223);  
We create an instance of the Color object.
MyObject obj1 = new MyObject(23, "small", col);
An instance of the MyObject object is created. It passes the instance of the Color object to its constructor.
MyObject obj2 = (MyObject) obj1.Clone();
We create a shallow copy of the obj1 object and assign it to the obj2 variable. The Clone() method returns an Object and we expect MyObject. This is why we do explicit casting.
obj2.id += 1;
obj2.size = "big";
obj2.col.red = 255;
Here we modify the member fields of the copied object. We increment the id, change the size to "big" and change the red part of the color object.
Console.WriteLine(obj1);
Console.WriteLine(obj2);
The Console.WriteLine() method calls the ToString() method of the obj2 object, which returns the string representation of the object.
$ ./shallowcopy.exe 
id: 23, size: small, color:(255, 42, 223)
id: 24, size: big, color:(255, 42, 223)
We can see, that the ids are different. 23 vs 24. The size is different. "small" vs "big". But the red part of the color object is same for both instances. 255. Changing member values of the cloned object (id, size) did not affect the original object. Changing members of the referenced object (col) has affected the original object too. In other words, both objects refer to the same color object in memory.

Deep Copy To change this behaviour, we will do a deep copy next.
using System;


public class Color : ICloneable
{
public int red;
public int green;
public int blue;

public Color(int red, int green, int blue)
{
this.red = red;
this.green = green;
this.blue = blue;
}

public object Clone()
{
return new Color(this.red, this.green, this.blue);
}
}

public class MyObject : ICloneable
{
public int id;
public string size;
public Color col;

public MyObject(int id, string size, Color col)
{
this.id = id;
this.size = size;
this.col = col;
}

public object Clone()
{
return new MyObject(this.id, this.size,
(Color) this.col.Clone());
}

public override string ToString()
{
string s;
s = String.Format("id: {0}, size: {1}, color:({2}, {3}, {4})",
this.id, this.size, this.col.red, this.col.green, this.col.blue);
return s;
}
}

public class CSharpApp
{
static void Main()
{
Color col = new Color(23, 42, 223);
MyObject obj1 = new MyObject(23, "small", col);

MyObject obj2 = (MyObject) obj1.Clone();

obj2.id += 1;
obj2.size = "big";
obj2.col.red = 255;

Console.WriteLine(obj1);
Console.WriteLine(obj2);
}
}
In this program, we perform a deep copy on object.
public class Color : ICloneable
Now the Color class implements the ICloneableinterface.
public object Clone()
{
return new Color(this.red, this.green, this.blue);
}
We have a Clone() method for the Color class too. This helps to create a copy of a referenced object.
public object Clone()
{
return new MyObject(this.id, this.size,
(Color) this.col.Clone());
}
Now, when we clone the MyObject, we call the Clone()method upon the col reference type. This way we have a copy of a color value too.
$ ./deepcopy.exe 
id: 23, size: small, color:(23, 42, 223)
id: 24, size: big, color:(255, 42, 223)
Now the red part of the referenced Color object is not the same. The original object has retained its previous 23 value.

Exceptions

Exceptions are designed to handle the occurrence of exceptions, special conditions that change the normal flow of program execution. Exceptions are raised or thrown, initiated.
During the execution of our application, many things might go wrong. A disk might get full and we cannot save our file. An Internet connection might go down and our application tries to connect to a site. All these might result in a crash of our application. To prevent happening this, we must cope with all possible errors that might occur. For this, we can use the exception handling.
The try, catch and finally keywords are used to work with exceptions.
using System;


public class CSharpApp
{
static void Main()
{
int x = 100;
int y = 0;
int z;

try
{
z = x / y;
} catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
In the above program, we intentionally divide a number by zero. This leads to an error.
try
{
z = x / y;
} catch (Exception e)
Statements that are error prone are placed after the trykeyword.
} catch (Exception e)
{
Console.WriteLine(e.Message);
}
Exception types follow the catch keyword. In our case we have a generic Exception which will catch an exception of any type. There are some generic exceptions and some more specific. Statements that follow the catch keyword are executed, when an error occurs. When an exception occurs, an exception object is created. From this object we get the Message property and print it to the console.
$ ./zerodivision.exe 
Division by zero
Output of the code example.

Any uncaught exception in the current context propagates to a higher context and looks for an appropriate catch block to handle it. If it can't find any suitable catch blocks, the default mechanism of the .NET runtime will terminate the execution of the entire program.
using System;


public class CSharpApp
{
static void Main()
{
int x = 100;
int y = 0;

int z = x / y;

Console.WriteLine(z);
}
}
In this program, we divide by zero. There is no no custom exception handling.
$ ./uncaught.exe 

Unhandled Exception: System.DivideByZeroException: Division by zero
at CSharpApp.Main () [0x00000]
The Mono C# compiler gives the above error message.

using System;
using System.IO;

public class CSharpApp
{

static void Main()
{
FileStream fs = new FileStream("langs", FileMode.OpenOrCreate);

try
{
StreamReader sr = new StreamReader(fs);
string line;

while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
} catch (IOException e)
{
Console.WriteLine("IO Error");
Console.WriteLine(e.Message);
} finally
{
Console.WriteLine("finally");
if (fs.CanRead)
{
fs.Close();
}
}
}
}
The statements following the finally keyword are always executed. It is often used to clean-up tasks, such as closing files or clearing buffers.
} catch (IOException e)
{
Console.WriteLine("IO Error");
Console.WriteLine(e.Message);
} finally
In this case, we catch for a specific IOException exception.
} finally
{
Console.WriteLine("finally");
if (fs.CanRead)
{
fs.Close();
}
}
These lines guarantee that the file handler is closed.
$ cat langs
C#
Python
C++
Java
$ ./finally.exe
C#
Python
C++
Java
finally
We show the contents of the langs file with the cat command and output of the program.

using System;
using System.IO;

public class CSharpApp
{

static void Main()
{
int x;
int y;
double z;

try
{
Console.Write("Enter first number: ");
x = Convert.ToInt32(Console.ReadLine());

Console.Write("Enter second number: ");
y = Convert.ToInt32(Console.ReadLine());

z = x / y;
Console.WriteLine("Result: {0:D} / {1:D} = {2:D}", x, y, z);

} catch (DivideByZeroException e)
{
Console.WriteLine("Cannot divide by zero");
Console.WriteLine(e.Message);
} catch (FormatException e)
{
Console.WriteLine("Wrong format of number.");
Console.WriteLine(e.Message);
} catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
In this example, we catch for various exceptions. Note that more specific exceptions should precede the generic ones. We read two numbers from the console and check for zero division error and for wrong format of number.
$ ./multipleexceptions.exe 
Enter first number: we
Wrong format of number.
Input string was not in the correct format
Running the example.

using System;

class BigValueException : Exception
{
public BigValueException(string msg) : base(msg) {}
}

public class CSharpApp
{
static void Main()
{
int x = 340004;
const int LIMIT = 333;

try
{
if (x > LIMIT)
{
throw new BigValueException("Exceeded the maximum value");
}
} catch (BigValueException e)
{
Console.WriteLine(e.Message);
}
}
}
Let's say, we have a situation in which we cannot deal with big numbers.
class BigValueException : Exception
We have a BigValueException class. This class derives from the built-in Exception class.
const int LIMIT = 333;
Numbers bigger than this constant are considered to be "big" by our program.
public BigValueException(string msg) : base(msg) {}
Inside the constructor, we call the parent's constructor. We pass the message to the parent.
if (x > LIMIT)
{
throw new BigValueException("Exceeded the maximum value");
}
If the value is bigger than the limit, we throw our custom exception. We give the exception a message "Exceeded the maximum value".
} catch (BigValueException e)
{
Console.WriteLine(e.Message);
}
We catch the exception and print its message to the console.
In this part of the C# tutorial, we continued the discussion of the object-oriented programming in C#.
Continue Reading