Home SEO Tools HTML Escape Tool Character Counter Guest post

Step By Step CSharp Tutorials for Beginners

0 comments


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.
Read More

Latest New features of CSharp

0 comments


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
Read More

CSharp New Features

0 comments


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#
Read More

Input And output in CSharp

0 comments


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#.
Read More

Collections in CSharp

0 comments


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#.


Read More

Namespaces in CSharp

0 comments


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.
Read More

Delegates in CSharp

0 comments


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.
Read More

FAQs | Privacy Policy | Contact | | Advertise | Donate