You are on page 1of 40

c# tutorial lesson 22: anonymous methods [2.

0]
note: this lesson covers new functionality in c# 2.0, which at the time of writing is not
released.
printer friendly version
in the original c# language, to construct a delegate object you have to provide it with the
name of a method. the code below shows an example: ‘print’ is first defined as a particular
delegate type, then its instance ‘delegatevariable’ is created by passing it the name of the
method ‘realmethod’.
1.
delegate void print (string s);

2.
print delegatevariable = new print(realmethod);

3.

4.
public void realmethod (string mystring)

5.
{

6.
messagebox.show(mystring);

7.
}

now, however, c# has been updated to include ‘anonymous’ methods (which should be pretty
easy for anyone who has used anonymous functions in languages like javascript). these allow
you to construct a delegate by specifying, rather than just naming a method. the following
gives an example of how the above code could be written using an anonymous method:
1.
public delegate void print (string s);

2.
print delegatevariable = delegate(string mystring) {messagebox.show(mystring);};

in the above case, the anonymous method is given the same signature as the delegate it is
passed to. but this is not always necessary. for the anonymous method to be acceptable, the
following two conditions must be met:
1. either the anonymous method has a parameter list that exactly matches the delegate’s
parameters; or the anonymous method has no parameter list and the delegate has no ‘out’
parameters.
2. either the values returned by the anonymous method are all of the right type for the
delegate; or the anonymous method doesn’t return anything and the delegate’s return type is
‘void’.
an implication of the first condition is that an anonymous method with no parameters at all
can fit a delegate with parameters. the following code is thus possible (notice that we’ve had
to remove the use of ‘mystring’ in the show method, because we’re no longer passing it in):
1.
public delegate void print (string s);

2.
print delegatevariable = delegate {messagebox.show(“hello world!”);};

outer types
anonymous methods can also make use of the local variables and parameters in whose scope
the anonymous method lies. this is a somewhat complicated, and we don’t yet have a clear
idea of when one should exploit it. so to illustrate it we’ll borrow the example from the
documentation.
1.
delegate int mydelegate();

2.
class test

3.
{

4.
static mydelegate myfunc()

5.
{

6.
int x=0;

7.
mydelegate result = delegate {return ++x;}

8.
return result;

9.
}

10.

11.
static void main()

12.
{

13.
mydelegate d = myfunc();

14.
console.writeline(d());

15.
console.writeline(d());

16.
console.writeline(d());

17.
}

18.
}

here the delegate ‘result’ declared in the function ‘myfunc’ makes use of (in the jargon,
captures) the integer ‘x’ which is declared in the same function. now, if we run the code, the
output is this:
1
2
3
this result is somewhat surprising, since the integer ‘x’ is instantiated and its value maintained
across three delegate calls after the function myfunc has finished running. how this is
described in the documentation is that the lifetime of the captured outer type is ‘extended’, so
that it lasts as long as any delegate that references it.
a further point to note is that in the example above each delegate is clearly referencing the
same type instance. but there are situations in which local variables get initialized many times
within a function, and these variables will count as different type instances. for example, in the
following loop, the integer i is initialised three times, and the delegates added into the
mydelegatearray will reference different variables.
1.
mydelegate[] mydelegatearray = new mydelegate[3];

2.
for (int x=0; x<3; x++)

3.
{

4.
int i = x;

5.
mydelegatearray[x] = delegate {return ++i};

6.
}

one question that this naturally raises is whether the multiple initialisation of i gives a
performance hit, which one could avoid by declaring i outside the loop. but the documentation
suggests that this isn’t the case; each new instance of i just slots neatly into the place vacated
by the previous one.

all tutorials

c# tutorial
the c# tutorial
contents
1 .net framework
2 c# vs c++/java
3 'hello world'
4 variable types
5 pointers
6 arrays
7 enumerations
8 operators
9 loops
10 jump/selection
11 classes...
12 ...declaration
13 methods
14 polymorphism
15 constants...
16 delegates...
17 exceptions
18 compiler
19 documentation
20 references
c# books (int)
c# books (uk)
patchwork book
21 [2.0] generics

22 [2.0] anon. methods

23 [2.0] iterators

24 [2.0] partial...

25 [2.0] nullable...
c# tutorial lesson 23: iterators [2.0]
printer friendly version
note: this lesson covers new functionality in c# 2.0, which at the time of writing is not
released.
to understand iterators we first need to understand enumerators.
enumerators are specialist objects which provide one with the means to move through an
ordered list of items one at a time (the same kind of thing is sometimes called a ‘cursor’). the
.net framework provides two important interfaces relating to enumerators: ienumerator and
ienumerable. objects which implement ienumerator are themselves enumerators; they support
the following members:
- the property current, which points to a position on the list
- the method movenext, which moves the current item one along the list
- the method reset, which moves the current item to its initial position (which is before the
first item).
objects which implement ienumerable, on the other hand, merely contract to provide
enumerators when a request is made to their getenumerator method (excitingly, an object
that implements both of these interfaces can return itself from the getenumerator method!)
with the onset of generics, there are now also the corresponding generic interfaces
ienumerator<t> and ienumerable<t>.
the other fact worth mentioning is that the ‘foreach’ statement can be used to iterate through
an ienumerable or an ienumerator instance. this is illustrated by the following code, which
uses the arraylist class (which implements ienumerable).
1.
arraylist arr = new arraylist();

2.
arr.add(obj1);

3.
arr.add(obj2);

4.

5.
foreach (object o in arr)

6.
{

7.
messagebox.show(o.tostring());

8.
}

the point of iterators is to allow the easy implementation of enumerators. where a method
needs to return either an enumerator or an enumerable class for an ordered list of items, it is
written so as to return each item in its correct order using the ‘yield’ statement. the following
code demonstrates this idea:
1.
public ienumerable getenumerator()

2.
{

3.
for (int x=0; x<itemarray.length; x++)

4.
yield return itemarray[x];

5.
}

note that the code author doesn’t create any enumerators or enumerables within the code; he
just ‘yields’ the outputs in the required order and lets the compiler take care of generating the
appropriate object.
in this example, the type of the objects listed by the generated enumerator is 'object'. where
one is using a generic interface like ienumerable<t>, the type of the objects listed by the
enumerator is 't'.
returning a subset of items
the example method given previously demonstrates the ‘yield return’ statement. there is also
the ‘yield break’ statement, which is used to indicate that the last item has been yielded. this
statement could be used to limit the number of items in the enumerator vended by the
method, as in the following example (which lacks some basic checks on array sizes):
1.
public ienumerable getshortenumerator(int l)

2.
{

3.
for (int x=0; x<itemarray.length; x++)

4.
{

5.
yield return itemarray[x];

6.
if (x==l)

7.
yield break;

8.
}
9.
}

c# tutorial lesson 24: partial types [2.0]


printer friendly version
note: this lesson covers new functionality in c# 2.0, which at the time of writing is not
released.
by using the new ‘partial’ class modifier, you can define a class across multiple files. the
compiled class merges the various partial source files into a single compiled class. so, for
instance, if you have the source code
1.
public partial class a

2.
{

3.
public void method1()

4.
{...}

5.
}

and somewhere else you have the source code


1.
public partial class a

2.
{

3.
public void method2()

4.
{...}

5.
}
then the compiled object will exhibit both method1 and method2. note that it’s important that
the various aspects of the declaration like modifiers, type parameters, etc. all match up across
the multiple partial declarations.
the stated reason for introducing the ‘partial’ modifier is that it’s fairly common for projects to
include some automated code generation. partial types supports code generation because it
means that code changes won’t necessarily be overwritten if code generation occurs anew; the
changes can be held in distinct files.
generally speaking, it is a compile-time error to declare two elements of the same class twice.
the only exceptions are for things like inner classes, which may themselves be declared as
partial.

c# tutorial lesson 25: nullable types [2.0]


note: this lesson covers new functionality in c# 2.0, which at the time of writing is not
released.
printer friendly version
c# now supports ‘nullable’ types: value types which are able to take the value ‘null’. the
reported reason for this change is to make it easier to integrate with databases, which may
hold null values in fields of any type.
the new nullable types are constructed using the ? symbol. for instance,
int?
is the new, nullable form of int. it is generally equivalent to int, except that it can take the
value null and has two associated properties: value and hasvalue. when the int? type is non-
null, the hasvalue property is set to true and the value property contains an int with the
numeric value. when hasvalue is set to false, on the other hand, the value property is not
available; an attempt to access it throws an exception.
in many cases there are implicit conversions between nullable types and the types on which
they are based. furthermore, the various standard operators (such as addition, etc.) work as
one would expect.
the ‘null coalescing operator’
a new operator has been introduced, consisting of two question marks, viz:
??
the effect of this operator in
x ?? y
is to return x except where x is null, in which case it returns y. so, for instance
int z = x ?? 0
always sets z to an integer value, which is zero when x is null. this new operator can also be
used on reference types.

c# tutorial lesson 21: generic types [2.0]


printer friendly version
note: this lesson covers new functionality in c# 2.0, which at the time of writing is not
released.
constructed types
instances of generic types come in different flavours, and when you declare an instance you
declare the flavour it has. to explain this in more concrete terms, let’s take a look at the
shortcomings of the otherwise useful system.collections.arraylist class.
an arraylist is used in situations where we want an array-like list, but can’t restrict the number
of elements it may contain. for instance, suppose that we need to keep track of a list of names
added into our application by the user. if the application is to support an indefinite number of
added names, then we could use an arraylist to store them. and, having stored them, the code
to print out the list might look something like this:
1.
for (int x=0; x<arrlist.count; x++)

2.
this.outputwindow.text += (string) arrlist[x];

notice in the above that there is an explicit cast to a string when pulling out the string element
from the arraylist. this is because arraylists, in order to be of general use, store their elements
as objects.
but this isn’t an ideal situation when all you want to add to the arraylist is strings. to make a
runtime cast isn’t very efficient, as it involves some background checks that the cast is valid.
what would be better would be if the arraylist could be declared as a string-only arraylist, so
that all type-safety checks could be run at compile time.
this is the kind of functionality provided by generics. when you declare a generic class you
specify one or more ‘type parameters’ (which comprise the ‘flavours’ we appealed to at the
start of this lesson). these type parameters then constrain the class instance in a way that
compilers can verify.
suppose that we wanted a generic version of the arraylist class, which could be declared as
interested only in strings. we might implement this using an internal array (though of course
this may not be the best way to do it), and a partial specification of the class would look
something like:
1.
public class arraylist<t>

2.
{

3.
private t[] itemarray;

4.

5.
public void add(t newitem)

6.
{...}

7.

8.
public t this[int i]

9.
{...}

10.
}
note how the type parameter t is included in angle brackets after the class name, and is used
throughout the class definition wherever the definable type is needed.
an instance of this generic arraylist class – what is called a (closed) constructed type – could
then be declared and used with code like the following, which replaces the type parameters
with type arguments:
1.
arraylist<string> strarrlist = new arraylist<string>();

2.
strarrlist.add(“fred”);

3.
string str = strarrlist[0];

after the constructed type has been set up, there is no need to cast the elements that are
added into or removed from it; these have to be strings, and failure to comply with this
requirement results in compile time errors.
note also that it is not just standard classes that can take generic forms; there can also be
generic structs, interfaces and delegates.
multiple type parameters
the example class given above used only one type parameter. but a generic class can have any
number of type parameters, which are separated both in the class definition and the instance
declaration with commas inside the angle brackets. the declaration of such a class might look
like this:
1.
public mygenericclass<t,u>

2.
{…}

all the examples in the draft literature use a capital letter to indicate a type parameter, so this
usage should be taken as good practice. however, since type parameters are named using
standard identifiers, there is no formal requirement to use capital letters (this is also an
implication, of course, of the fact that there is no limit to the number of type parameters a
class may have).
it is possible to have classes with the same name but different numbers of class parameters
(note that it is the number of class parameters, not their identifiers that is important). so, for
instance, you could have both the following classes declared within the same namespace:
1.
public mygenericclass<t>

2.
public mygenericclass<t,u>
but not these:
1.
public mygenericclass<t,u>

2.
public mygenericclass<v,w>

generic methods
standard, non-generic classes can have generic methods, which are methods that are declared
with type parameters. both the inputs and the outputs of these methods may reference the
type variables, allowing code such as:
1.
public t mymethod<t>(mygenericclass<t>) {}

overloading occurs on methods analogously to the way it occurs on classes; the number of
type parameters a method has is used to distinguish it from other methods.
it is possible to call generic methods without actually giving a type argument; this relies upon
a process of type inference. for example, the method given above could be called using code
like:
1.
mygenericclass<int> myg = new mygenericclass<int>();

2.
int i = mymethod(myg);

type inference involves the compiler working out which type argument must have been meant
given the way the method was invoked. it seems dubious to us, however, that the brevity it
provides outweighs the clarity of leaving in the type argument.
note that while there are generic forms of methods, there are no generic forms of properties,
nor of events, indexers and operators.
type constraints
until now, we have implicitly assumed that any type argument may be provided for any type
parameter. but it is possible to restrict the range of possible values for each type parameter by
specifying constraints.
the following code comprises the header of a definition for the generic class mygenericclass.
the two ‘where’ clauses (which are placed on separate lines for readability only) provide the
constraints. the first clause restricts the first type parameter t to types which are - or which
sub-class - the myconstraint class. the second clause extends this constraint on u to
myconstraint types which also satisfy the myinterface interface.
1.
public class mygenericclass<t,u>

2.
where t: myconstraint

3.
where u: myconstraint, myinterface

4.
{...}

note that a single constraint can mention any number of interfaces, but a maximum of one
class.
why might we want to place a constraint on a type parameter? well, suppose that we wanted
to implement a bubble-sort routine in the ‘sort’ method for our generic arraylist class. in this
case it would be useful to restrict the types we’re dealing with to those which implement the
icomparable interface (which ensures that any two elements of the same type can be ranked).
this allows us to use the ‘compareto’ method without having to make any runtime casts or trap
errors, as shown by the following code.
1.
public class arraylist<t> where t: icomparable

2.
{

3.
private t[] itemarray;

4.
public void sort()

5.
{

6.
for (int x=1; x<itemarray.length; x++)

7.
{

8.
for (int y=0; y<x; y++)

9.
{

10.
int z = x-y;

11.
t itemhigher = itemarray[z];
12.
t itemlower = itemarray[z-1];

13.
if (itemlower.compareto(itemhigher)>0)

14.
{

15.
itemarray[z] = itemlower;

16.
itemarray[z-1] = itemhigher;

17.
}

18.
}

19.
}

20.
}

21.
}

c# tutorial lesson 20: further references


as c# is finalized, and more resources built up around it, we shall be looking to add to this
references page.
c# language reference
http://msdn.microsoft.com/net/ecma/
.net download
http://msdn.microsoft.com/netframework/downloads/updates/default.aspx
general portals
microsoft community website for .net generally
http://www.gotdotnet.com/
microsoft visual c# development centre
http://msdn.microsoft.com/vcsharp/team/default.aspx
information, links and other resources for the c# language
http://www.csharp-station.com/
c# articles, forum, etc.
http://www.pune-csharp.com/
collections of articles
working with c# (and other papers)
http://www.msdn.microsoft.com/columns/
.net home page at microsoft
http://www.msdn.microsoft.com/netframework/
the o'reilly c# page
http://www.oreillynet.com/topics/dotnet/csharp.net
code-project: useful code help
http://www.codeproject.com/csharp/
codeguru
http://codeguru.earthweb.com/csharp/index.shtml
c# discussion
gotdotnet message board
http://www.gotdotnet.com/community/messageboard/messageboard.aspx?id=6
microsoft public newsgroup (web frontend)
http://communities.microsoft.com/newsgroups/default.asp?icp=dotnet&slcid=us
codeguru discussion board
http://codeguru.earthweb.com/cgi-bin/bbs/wt/wwwthreads.pl?action=list&board=csharp
open source c# projects
the mono project is an attempt to create an open source implementation of the .net
framework, including a c# compiler
http://www.mono-project.com/about/index.html
the dotgnu project is trying to provide alternatives for all elements of the microsoft .net
strategy, especially its hailstorm application. it also includes a c# compiler.
http://www.gnu.org/projects/dotgnu/
book lists
we now are drawing book lists from amazon, but adding in some functionality to list by date
published, amazon rating, etc. see c# books from amazon.com or c# books from
amazon.co.uk.

c# tutorial lesson 19: code documentation


printer friendly version
the c# compiler supports the automatic creation of class documentation. where the equivalent
functionality for java produces html, the c# documenter produces xml. this means that the c#
documentation is not as immediately ready to use as the java documentation. however, it does
allow there to be different applications which can import and use the c# documentation in
different ways. (note: using visual studio you can also create html documentation, but we will
not be covering this here).
sadly, microsoft did not bundle a basic documentation reader with c#.. even worse, however,
the documentation automatically produced by c# is rather less extensive than that produced
by java’s javadoc tool. indeed, as we note in the final section of this lesson, this xml
documentation is so lacking that we have been driven to write an alternative documenter.
c# documentation comments
to document any element in a c# script, you precede the element with xml elements. each of
the lines comprising this documentary code should be marked off as comments using the
following special comment indicator (you can compare this with the standard comment
indicators in lesson 3)
///
the following code gives an example of how one can provide overview information about a
class.
1.
/// <summary>

2.
/// the myclass class represents an arbitrary class

3.
/// </summary>
4.
public class myclass

you are at liberty to use any xml tags you wish to document the code – as long as they follow
the xml syntax then the compiler will happily write them into the documentation. but microsoft
does provide a list of recommended xml elements for you to use. some of these elements
indicate the type of documentary information that is being given, and the compiler will validate
certain aspects of these. other elements are just used to give layout or formating information.
the following lists describe the main documentation elements provided. note that the content
of each element should be written between its opening and closing tags, and some of the tags
also take further attributes. in particular, the ‘cref’ attribute can supposedly be used in any
element, but we have just used it in the cases where it seems particularly appropriate.
tag(s) description
<summary> - holds overview information about any documentable element.
<remarks> - allows for expanded comments about any documentable element,
following summary information.
note: we still aren’t sure if the descriptions of the tags above are correct. the following points
describe the problem.
in favour of using the 'summary' and 'remarks' in the suggested way is the fact that
gunnarson, who helped create c#, sets things out in this way. it also correlates with the
default behaviour of visual studio.net, where ‘summary’ tags are given by default whenever
you start documenting any element.
on the other hand, in the help files of the (production) version of .net – v. 1.0.3705 – it
explicitly states that the use of ‘summary’ is to hold overview information about a class
member, whereas the use of ‘remarks’ is to hold overview information about a class. however,
some of the examples given throughout these same help files conflicts with this advice - for
example, in the description of the ‘paramref’ element, a class method is documented only with
‘remarks’. unfortunately, of course, this example also conflicts with what we say, since the
example contains no ‘summary’ tag.
basically, it’s all been knocked together by a committee of rather befuddled monkeys. but the
way we suggest is as good as any.
tag(s) description
<param - describes a parameter passed to a method. the compiler
name="name"> checks that the ‘name’ value matches an actual parameter in
the code. also, if you give documentation for one parameter
value, the compiler will expect you to give documentation for
them all.
<paramref - identifies the mention of a parameter name within some
name="name"> other descriptive element, for instance within ‘summary’ tags.
the idea is that this mentioned name can be styled differently
from the surrounding text. the compiler checks that the
‘name’ value matches an actual parameter in the code.
<returns> - describes the return value for a method. as the descriptive
field is just free text there is no compiler checking.
<exceptions - describes an exception that may be thrown by a method. the
cref="type"> ‘cref’ attribute refers to a type or field (such as
system.exception), and the compiler checks that this
reference is available from the current compilation
environment.
<permission - describes a permission requirement for a type or member.
cref="type"> the cref attribute refers to a type or field (such as
system.security.permissionset), and the compiler checks that
this reference is available from the current compilation
environment.
<value> - describes a class property.
<example> - gives an example of the use of the referenced object (for
example a class method). the ‘example’ element is often used
with the following two elements.
<c> - marks up a single phrase or line as a code example.
generally used in conjuction with the ‘example’ element.
<code> - marks up multiple lines as code examples. generally used in
conjuction with the ‘example’ element.
<see cref - used to identify a cross-reference in the documentation;
="type"> designed to be used inline within a description element. the
cref attribute refers to a type or field, and the compiler checks
that this reference is available from the current compilation
environment. and the see also tag is used in a separate
section. this allows the documentation to create cross-
references.
<seealso cref - used to identify a cross-reference in the documentation;
="type"> different from ‘see’ in that it is designed to stand alone. the
cref attribute refers to a type or field, and the compiler checks
that this reference is available from the current compilation
environment.
the following elements are just used to provide layout information:
<para> - used within descriptive tags like ‘remarks’, ‘summary’, etc. to
wrap a single paragraph.
<list type = - top level tags for a list, where this may be one of the three
”bullet” | types shown.there are more elements associated with the list
“number” | tag: the following code gives an example of these.
“table”>
<list type="table">
<listheader>
<term>animal</term>
<description>type</description>
</listheader>
<item>
<term>monkey</term>
<description>hairy</description>
</item>
<item>
<term>pig</term>
<description>bald</description>
</item>
</list>
note - in relation to the example of the 'list' tag given above - that the v. 1.0.3705 help
documentation for the enclosed 'item' tag talks about a ‘text’ element in place of the second
‘description’. but this seems to be just wrong.
generating c# documentation
you tell the compiler to produce documentation when compiling by invoking it with the switch:
/doc:file
in this switch, file represents the name of the file that you want the documentation written to.
as the documentation is generated in xml format, the file should have the extension .xml. so,
for instance, to produce the documentation for a program in sys.cs file in a file named my.xml,
we would use the command:
csc sys.cs /doc:my.xml
those working with visual studio .net should set the ‘xml documentation file’ property in the
‘build’ directory of the project’s configuration properties.
problems with the c# documenter
the c# documenter is lacking in many different areas. here are just a couple of problems that
make the documenter hard to live with.
firstly, if you don’t document a method, the documenter just ignores it (or else throws a
warning). this forces you to document all methods, no matter how simple and obvious they
might be, which is annoying when the computer could easily do it for you.
secondly, while the compiler checks the parameter types of methods, even to the extent of
providing the fully qualified parameter name, it fails to do this with the return values of
methods. the user has to manually insert the return type, even though the compiler could
easily produce this.
there is a solution, however...
the softsteel documenter
driven by documentation frustration, the softsteel team (well, andy really, but we all chipped
in with biscuits), has produced a command-line documenter, written in c#. it’s quite rusty at
the moment, but is already a whole load better than the inbuilt documenter. we’re working on
improvements, but we’re releasing it as free software under the gnu gpl in order to encourage
community support.
the downloads for the documentation tool are now being handled by the download page
http://www.softsteel.co.uk/tutorials/csharp/download.asp

c# tutorial lesson 18: using the c# compiler


printer friendly version
as we have noted earlier, c# classes are compiled in the first place to the common language
runtime intermediate language (il). and as shown in lesson 3, one compiles these classes
using the command-line command
csc file.cs
where the required classes are held in more than one file, these should be listed, separated by
spaces, as in:
csc file1.cs file2.cs
broadly speaking, one can compile c# classes into either executable files or dynamic link
library - dll - files (see the /t switch in the table below). an executable file is one that can
contains a runnable program (note that in the classes compiled to an executable file, there
should be only one 'main' method). a .net dynamic link library just collects together an
assembly of classes, which can then be instantiated and utilised by programs in the course of
their running.
if your classes reference external classes, the c# compiler must be able to locate them. by
default, the compiler only looks within the 'mscorlib.dll' assembly, which supports the basic
common language runtime functions. to point the compiler in the direction of other classes,
use the /r switch described in the table below (note that there is no equivalent to the java
approach of setting the environment variable classpath). to find the appropriate assembly for
.net framework classes, consult their documentation.
the following gives a list of the compiler switches we have found useful, but we would advise
you to look further at the .net documentation to see which other ones are available.
compiler switch description
/r:dll or /reference:dll this tells the c# compiler to include one or more of
eg. the .net framework dlls. as the standard library
/r:system.xml.dll, namespaces are not automatically referenced by
system.net.dll the compiler, it is necessary to tell it which ones are
needed. this switch also allows you to include your
own dlls.
/out: file specifies the filename to which the compiled code is
eg. to be written.
/out:fred.dll
/doc: file requests the production of xml documentation into
eg. the specified file (see lesson 19).
/doc:doc.xml
/t:type or /target:type this is used to specify the type of output file
eg. produced
/t:exe - produce a console
executable file (default)
/t:library - produce a dll file
/t:module - creates each
file into its own dll, eg.
fred.cs will be converted to
fred.dll
/t:winexe - produce a
windows executable file
if you are regularly compiling a program and using a lot of switches in your program, we have
found it useful to put the compile command in a batch file rather than writing out the entire
command each time.
preprocessor directives
preprocessor directives tags included within class specifications; they are used to give the
compiler additional information about regions of code. the following example shows that you
can specify areas of code to be compiled or not, depending upon the presence of a tag:
1.
/*

2.
preprocessor test

3.
*/

4.

5.
#define myvar

6.
public class pretest

7.
{

8.
public static void main()
9.
{

10.
#if myvar

11.
print ("hello");

12.
#endif

13.
print ("andy");

14.
}

15.
}

in the above, the #define statement on line 5 acts as a boolean: it sets the variable myvar to
be 'defined' rather than 'undefined'. because it is defined, the code on line 16 gets compiled. if
we were to remove the statement on line 5, the compiler would effectively treat the code on
line 11 as commented out.
note: in the previous version of this page we followed the msdn documentation in using as our
example the variable debug. but it has been pointed out to us by a correspondent that the
debug variable is already defined by visual studio.net when a project is compiled as 'debug'
rather than 'release'. so if you're building from vs.net you wouldn't want to explicitly redefine
the variable debug like this.
the following gives a list of some of the available preprocessor directives.
directive action
#define symbol sets symbol to be 'defined' (true)
#undef symbol sets symbol to be 'undefined' (false)
#if symbol the if statement evaluates the given expression. the possible
[operator operators can be ==, !=, &&, ||. if the expression evaluates
symbol2] to 'true', the code to the #else, #elif or #endif directive is
compiled.
#else used in conjunction with the if statement.
#elif used in conjunction with the if statement as 'else-if'.
#endif ends the previous conditional directives
#warning text the given text appears as a warning in the compiler output
#error text the given text appears as an error in the compiler output
#line outputs a line number, and (optionally) a filename to the
number[file] compiler output.
#region name marks the beginning of a region
#end region marks the ends of a region
attributes
attributes are used to give extra information to the .net compiler. c# and the .net framework
have a few built-in attribute types, but it is also possible to create new ones by extending the
system.attribute class. below we describe a few common uses of attributes.
it is possible to tell the compiler that a class is compliant with the .net common language
specification (discussed in lesson 1) with code like the following:
1.
using system;

2.

3.
[clscompliant(true)]

4.
public class myclass

5.
{

6.
// class code

7.
}

similar code can also be used to indicate that a class has been obsoleted.
web services (mentioned in lesson 1) also make heavy use of attributes. demonstrated by the
example below, the attribute [ webmethod ] is used to specify that a particular method is to
be exposed as a web service.
1.
[ webmethod ]

2.
public int add(int num1, int num2)

3.
{

4.
return num1+num2;

5.
}

c# tutorial lesson 17: exceptions


printer friendly version
the exception handling in c#, and java is quite similar. however, c# follows c++ in allowing the
author to ignore more of the exceptions that might be thrown (an exception which is thrown
but not caught will halt the program and may throw up a dialogue box).
to catch a particular type of exception in a piece of code, you have to first wrap it in a 'try'
block and then specify a 'catch' block matching that type of exception. when an exception
occurs in code within the 'try' block, the code execution moves to the end of the try box and
looks for an appropriate exception handler. for instance, the following piece of code
demonstrates catching an exception specifically generated by division by zero:
1.
try

2.
{

3.
int zero = 0;

4.
res = (num / zero);

5.
}

6.
catch (system.dividebyzeroexception e)

7.
{

8.
console.writeline("error: an attempt to divide by zero");

9.
}

you can specify multiple catch blocks (following each other), to catch different types of
exception. a complication results, however, from the fact that exceptions form an object
hierarchy, so a particular exception might match more than one catch box. what you have to
do here is put catch boxes for the more specific exceptions before those for the more general
exceptions. at most one catch box will be triggered by an exception, and this will be the first
(and thus more specific) catch box reached.
following the last 'catch' box you can also include a 'finally' box. this code is guaranteed to run
whether or not an exception is generated. it is especially useful for cleanup code where this
would be skipped in the 'try' box following an exception being thrown.
where an exception is not caught by any of the subsequent 'catch' boxes, the exception is
thrown upwards to the code which called the method in which the exception occurred (note
that in c# the methods do not declare what exceptions they are throwing). this exception will
keep on bubbling upwards until it is either caught by some exception handling in the code, or
until it can go no further and causes the program to halt.
note that the exceptions a program throws need not be limited to those automatically
generated. a program can throw exceptions - including customised exceptions - whenever it
wishes, using the 'throw' command. the code below gives examples of all the statements
discussed above, with the 'getexception' method showing how to throw an exception.
1.
using system;

2.
public class exceptiondemo

3.
{

4.
public static void main ()

5.
{

6.
try

7.
{

8.
getexception();

9.
}

10.
catch (exception e)

11.
{

12.
console.writeline("we got an exception");

13.
}

14.
finally

15.
{

16.
console.writeline("the end of the program");

17.
}

18.
}

19.
20.
public static void getexception()

21.
{

22.
throw new exception();

23.
}

24.
}

c# tutorial lesson 16: delegates and events


printer friendly version
delegates are reference types which allow indirect calls to methods (lesson 13). a delegate
instance holds references to some number of methods, and by invoking the delegate one
causes all of these methods to be called. the usefulness of delegates lies in the fact that the
functions which invoke them are blind to the underlying methods they thereby cause to run
(see, for instance, the discussion of events, below).
from this brief description, it can be seen that delegates are functionally rather similar to
c++'s 'function pointers'. however, it is important to bear in mind two main differences. firstly,
delegates are reference types rather than value types (for the difference see lesson 4).
secondly, some single delegates can reference multiple methods
delegate declaration and instantiation
delegates can be specified on their own in a namespace, or else can be specified within
another class (the examples below all show the latter). in each case, the declaration specifies
a new class, which inherits from system.multicastdelegate.
each delegate is limited to referencing methods of a particular kind only. the type is indicated
by the delegate declaration - the input parameters and return type given in the delegate
declaration must be shared by the methods its delegate instances reference. to illustrate this:
a delegate specified as below can be used to refer only to methods which have a single string
input and no return value:
public delegate void print (string s);
suppose, for instance, that a class contains the following method:
1.
public void realmethod (string mystring)

2.
{

3.
// method code

4.
}
another method in this class could then instantiate the 'print' delegate in the following way, so
that it holds a reference to 'realmethod':
print delegatevariable = new print(realmethod);
we can note two important points about this example. firstly, the unqualified method passed to
the delegate constructor is implicitly recognised as a method of the instance passing it. that is,
the code is equivalent to:
print delegatevariable = new print(this.realmethod);
we can, however, in the same way pass to the delegate constructor the methods of other class
instances, or even static class methods. in the case of the former, the instance must exist at
the time the method reference is passed. in the case of the latter (exemplified below), the
class need never be instantiated.
print delegatevariable = new print(exampleclass.examplemethod);
the second thing to note about the example is that all delegates can be constructed in this
fashion, to create a delegate instance which refers to a single method. however, as we noted
before, some delegates - termed 'multicast delegates' - can simultaneously reference multiple
methods. these delegates must - like our print delegate - specify a 'void' return type.
one manipulates the references of multicast delegates by using addition and subtraction
operators (although delegates are in fact immutable reference types - for explanation of the
apparent contradiction see the discussion of strings in lesson 4). the following code gives some
examples:
1.
print s = null;

2.
s = s + new print (realmethod);

3.
s += new print (otherrealmethod);

the - and -= operators are used in the same way to remove method references from a
delegate.
the following code gives an example of the use of delegates. in the main method, the print
delegate is instantiated twice, taking different methods. these print delegates are then passed
to the display method, which by invoking the print delegate causes the method it holds to run.
as an exercise, you could try rewriting the code to make print a multicast delegate.
1.
using system;

2.
using system.io;

3.

4.
public class delegatetest

5.
{

6.
public delegate void print (string s);

7.

8.
public static void main()

9.
{

10.
print s = new print (toconsole);

11.
print v = new print (tofile);

12.
display (s);

13.
display (v);

14.
}

15.

16.
public static void toconsole (string str)

17.
{

18.
console.writeline(str);

19.
}

20.

21.
public static void tofile (string s)

22.
{

23.
streamwriter fileout = file.createtext("fred.txt");

24.
fileout.writeline(s);

25.
fileout.flush();

26.
fileout.close();

27.
}

28.

29.
public static void display(print pmethod)

30.
{

31.
pmethod("this should be displayed in the console");

32.
}

33.
}

events
to recap: in object-oriented languages, objects expose encapsulated functions called methods.
methods are encapsulated functions which run when they are invoked.
sometimes, however, we think of the process of method invocation more grandly. in such a
case, the method invocation is termed an 'event', and the running of the method is the
'handling' of the event. an archetypal example of an event is a user's selection of a button on
a graphical user interface; this action may trigger a number of methods to 'handle' it.
what distinguishes events from other method invocations is not, however, that they must be
generated externally. any internal change in the state of a program can be used as an event.
rather, what distinguishes events is that they are backed by a particular 'subscription-
notification' model. an arbitrary class must be able to 'subscribe to' (or declare its interest in)
a particular event, and then receive a 'notification' (ie. have one of its methods run) whenever
the event occurs.
delegates - in particular multicast delegates - are essential in realizing this subscription-
notification model. the following example describes how class 2 subscribes to an event issued
by class 1.
1. class 1 is an issuer of e-events. it maintains a public multicast delegate d.

2. class 2 wants to respond to e-events with its event-handling method m. it


therefore adds onto d a reference to m.

3. when class 1 wants to issue an e-event, it calls d. this invokes all of the
methods which have subscribed to the event, including m.
the 'event' keyword is used to declare a particular multicast delegate (in fact, it is usual in the
literature to just identify the event with this delegate). the code below shows a class
eventissuer, which maintains an event field myevent. we could instead have declared the
event to be a property instead of a field (for the difference between these see lesson 15). to
raise the myevent event, the method onmyevent is called (note that we are checking in this
method to see if myevent is null - trying to trigger a null event gives a run-time error).
1.
public class eventissuer

2.
{

3.
public delegate void eventdelegate(object from, eventargs
args);

4.
public event eventdelegate myevent;

5.

6.
protected virtual void onmyevent(eventargs args)

7.
{

8.
if (myevent!=null)

9.
myevent(this, args);

10.
}

11.

a class which wanted to handle the events issued by an eventissuer ei with its method
handleevents would then subscribe to these events with the code:
ei.myevent += new eventissuer.eventdelegate(handleevents);

good practice for events


the code above demonstrates some points about event-handling which are not enforced by the
language architecture, but are used throughout the .net framework as good practice.
1. when you want to raise an event in code, you don't tend to trigger the class's event object
directly. rather, you call a 'protected, virtual' method to trigger it (cf. the onmyevent method
above).
2. by convention, when events are raised they pass two objects to their subscribers. the first is
a reference to the class raising the event; the second is an instance of the system.eventargs
class which contains any arbitrary data about the event.
3. if an event is not interested in passing data to subscribers, then its defining delegate will
still reference an eventargs object (but a null value will be passed by the event). if an event
should pass data to its subscribers, however, then it is standard to use a specific class which
derives from the eventargs class to hold this data.
4. when you write a class which inherits from an event-raising base class, you can 'intercept'
an event by overriding the method used to raise it. the following code illustrates such an
intercept - classes which subscribe to the event will never receive notifications about it.
1.
protected override void onmyevent(eventargs args)

2.
{

3.
console.writeline("hello");

4.
}

5.

if you want subscribers to continue to receive notifications despite such an 'intercepting'


method, however, then you can call the base class method as in the following:
1.
protected override void onmyevent(eventargs args)

2.
{

3.
console.writeline("hello");

4.
base.onmyevent(args);

5.
}

6.

c# tutorial lesson 15: constants, fields, properties and indexers


printer friendly version

fields
fields are variables associated with either classes or instances of classes. there are seven
modifiers which can be used in their declarations. these include the four access modifiers
'public', 'protected', 'internal' and 'private' (discussed in lesson 12) and the 'new' keyword
(discussed in lesson 14). the two remaining modifiers are:
static
by default, fields are associated with class instances. use of the 'static' keyword, however,
associates a field with a class itself, so there will only ever be one such field per class,
regardless of the number of the class instances (and the static field will exist even if there are
no class instances). a static field need not be constant, however; it can be changed by code. in
the following code example the 'setstaticfield' method illustrates such a change.
1.
public class myclass

2.
{

3.
public static int staticfield = 1;

4.

5.
public myclass()

6.
{}

7.

8.
public void setstaticfield(int i)

9.
{

10.
myclass.staticfield = i;

11.
}

12.
}

readonly
where a field is readonly, its value can be set only once, either in the class declaration, or (for
non-static fields only) in the class constructor. the following code example (which, please note,
deliberately doesn't compile) shows both cases: the field staticreadonlyint is set in the class
declaration; the field readonlystring is set in the class constructor.
1.
public class myclass
2.
{

3.
public static readonly int staticreadonlyint = 1;

4.
public readonly string readonlystring;

5.

6.
public myclass()

7.
{

8.
readonlystring = "test";

9.
}

10.

11.
// this method doesn't compile

12.
public void notcompile()

13.
{

14.
myclass.staticreadonlyint = 4;

15.
this.readonlystring = "test2";

16.
}

17.
}

while we're on declarations, note also that a field declaration can involve multiple fields, as in
the following line of code
public static int a = 1, b, c = 2;
which is equivalent to
public static int a = 1;
public static int b;
public static int c = 2;

constants
constants are unchanging types, associated with classes, that are accessible at compile time.
because of this latter fact, constants can only be value types rather than reference types.
constant declarations take the 'const' keyword (not 'static', even though they are associated
with classes), and the five modifiers 'public', 'protected', 'internal', 'private' and 'new'.
the following is a simple constant declaration, although multiple constants can be
simultaneously declared.
public const int area = 4;
if you've been reading carefully, you may be struck by the thought: what's the difference
between declaring a field as 'const' and declaring a field 'static readonly'. good question. i'll
leave it to the professionals to provide the definitive answer, but the general point is that
static readonly fields can be reference types as well as value types.
properties
properties can be thought of as 'virtual' fields. from the outside, a class' property looks just
like a field. but from the inside, the property is generated using the actual class fields.
property declarations take just those modifiers taken by methods (see lesson 13) unlike
languages like java, c# provides dedicated support for accession and mutation of these
properties. suppose, for instance, that a type contains an internal field called 'age'. with the
following code one could specify a property age, providing accessors and mutators to this
internal field.
1.
public int age

2.
{

3.
get

4.
{

5.
return this.age;

6.
}

7.
set

8.
{

9.
this.age = value;

10.
}

11.
}
notice that the term 'value' is used in the above piece of code. this variable always holds the
value passed to the 'set' block. for instance, the execution of the following line of code
(assuming the appropriate class instance) would automatically set 'value' in the 'set' block to
4.
person.age = 4;
this property age can be described as 'read-write' since it can be both read from and written
to. to make a property 'write-only' one simply does not specify a 'get' block; to make it 'read-
only' one does not specify a 'set' block. the following piece of code demonstrates the read-only
property 'adult':
1.
public bool adult

2.
{

3.
get

4.
{

5.
if (this.age<18)

6.
return false;

7.
else

8.
return true;

9.
}

10.
}

indexers
if properties are 'virtual fields', indexers are more like 'virtual arrays'. they allow a class to
emulate an array, where the elements of this array are actually dynamically generated by
function calls.
the following piece of code defines a class to hold a list of runners in an athletics race. the
runners are held in lane order, and an indexer is exposed which allows the list to be both read
from and written to. the indexer deals gracefully with cases in which the lane number passed
to it is either too high or too low.
1.
class racedetails

2.
{

3.
private string[] lanes;

4.

5.
public racedetails()

6.
{

7.
this.lanes = new string[8];

8.
}

9.

10.
public string this[int i]

11.
{

12.
get

13.
{

14.
return (i>=0 && i<8) ? this.lanes[i] : "error";

15.
}

16.

17.
set

18.
{

19.
if (i>=0 && i<8) this.lanes[i] = value;
20.
}

21.
}

22.
}

the following simple code illustrates use being made of the class just defined. the name of the
person in the race's first lane is set, and then this name is sent to a console window.
1.
racedetails rd = new racedetails();

2.
rd[0] = "fred";

3.
console.writeline("lane one : " + rd[0]);

as can be seen from the example, an indexer is defined in a similar way to a property. one
important difference is in the indexer's signature; the word 'this' is used in place of a name,
and after this word indexing elements are provided.
indexers aren't differentiated by name, and a class cannot declare two indexers with the same
signature. however, this does not entail that a class is limited to just one indexer. different
indexers can have different types and numbers of indexing elements (these being equivalent
to method parameters, except that each indexer must have at least one indexing element, and
the 'ref' and 'out' modifiers cannot be used).
because indexing elements are not limited to integers, the original description of indexers as
'virtual arrays' actually rather undersells them. for example, where the indexing elements
include strings, indexers present themselves more like hash tables.
the following code shows an implementation for the racedetails class of an indexer whose
indexing element is a string. using this indexer it is possible to refer to a lane using the name
of the person currently filling that lane.
1.
public string this[string s]

2.
{

3.
get

4.
{

5.
int lanenum = getcorrespondinglane(s);

6.
return (lanenum<0) ? "error" : this.lanes[lanenum];

7.
}

8.

9.
set

10.
{

11.
int lanenum = getcorrespondinglane(s);

12.
if (lanenum>=0) this.lanes[lanenum] = value;

13.
}

14.
}

15.

16.
private int getcorrespondinglane(string myname)

17.
{

18.
for (int x=0; x<lanes.length; x++)

19.
{

20.
if (myname==lanes[x]) return x;

21.
}

22.
return -1;

23.
}
the following piece of code gives an example of the kind of use one might make of this string
indexer.
1.
rd["fred"] = "jill";

c# tutorial lesson 14: polymorphism


(inherited methods)
printer friendly version
as we have seen previously (lesson 11), classes take on the
methods of the classes from which they inherit. in some cases,
however, a class may want to 'overwrite' such a method. c#
supports two different ways of method overwriting - 'hiding' or
'overriding'. note that the term 'overwrite' is a term we have
devised to cover both hiding and overriding.
method overwriting makes use of the following three method-head
keywords (see lesson 13):
new, virtual, override
the main difference between hiding and overriding relates to the
choice of which method to call where the declared class of a
variable is different to the run-time class of the object it
references. this point is explained further below.
method overriding
suppose that we define a square class which inherits from a
rectangle class (a square being a special case of a rectangle). each
of these classes also specifies a 'getarea' instance method,
returning the area of the given instance.
for the square class to 'override' the rectangle class' getarea
method, the rectangle class' method must have first declared that
it is happy to be overridden. one way in which it can do this is with
the 'virtual' keyword. so, for instance, the rectangle class' getarea
method might be specified like this:
1.
public virtual double getarea()

2.
{

3.
return length * width;

4.
}
to override this method the square class would then specify the
overriding method with the 'override' keyword. for example:
1.
public override double getarea()

2.
{

3.
return length * length;

4.
}

note that for one method to override another, the overridden


method must not be static, and it must be declared as either
'virtual', 'abstract' or 'override'. furthermore, the access modifiers
for each method must be the same.
the major implication of the specifications above is that if we
construct a new square instance and then call its 'getarea'
method, the method actually called will be the square instance's
getarea method. so, for instance, if we run the following code:
square sq = new square(5);
double area = sq.getarea();
then the getarea method called on the second line will be the
method defined in the square class.
there is, however, a more subtle point. to show this, suppose that
we declare two variables in the following way:
square sq = new square(4);
rectangle r = sq;
here variable r refers to sq as a rectangle instance (possible
because the square class derives from the rectangle class). we can
now raise the question: if we run the following code
double area = r.getarea();
then which getarea method is actually called - the square class
method or the rectangle class method?
the answer in this case is that the square class method would still
be called. because the square class' getarea method 'overrides'
the corresponding method in the rectangle class, calls to this
method on a square instance always 'slide through' to the
overriding method.
method hiding
where one method 'hides' another, the hidden method does not
need to be declared with any special keyword. instead, the hiding
method just declares itself as 'new'. so, where the square class
hides the rectangle class' getarea method, the two methods might
just be written thus:
1.
public double getarea() // in rectangle

2.
{

3.
return length * width;

4.
}

1.
public new double getarea() // in square

2.
{

3.
return length * length;

4.
}

note that a method can 'hide' another one without the access
modifiers of these methods being the same. so, for instance, the
square's getarea method could be declared as private, viz:
1.
private new double getarea()

2.
{

3.
return length * length;

4.
}

this leads us to an important point. a 'new' method only hides a


super-class method with a scope defined by its access modifier.
specifically, where the access level of the hiding method is
'private', as in the method just described, this method only hides
the super-class method for the particular class in which it is
defined.
to make this point more concrete, suppose that we introduced a
further class, specialsquare, which inherits from square. suppose
further that specialsquare does not overwrite the getarea method.
in this case, because square's getarea method is defined as
private, specialsquare inherits its getarea method directly from the
rectangle class (where the getarea method is public).
the final point to note about method hiding is that method calls do
not always 'slide through' in the way that they do with virtual
methods. so, if we declare two variables thus:
square sq = new square(4);
rectangle r = sq;
then run the code
double area = r.getarea();
the getarea method run will be that defined in the rectangle class,
not the square class.

all tutorials

c# tutorial
the c# tutorial
contents
1 .net framework
2 c# vs c++/java
3 'hello world'
4 variable types
5 pointers
6 arrays
7 enumerations
8 operators
9 loops
10 jump/selection
11 classes...
12 ...declaration
13 methods
14 polymorphism
15 constants...
16 delegates...
17 exceptions
18 compiler
19 documentation
20 references
c# books (int)
c# books (uk)
patchwork book
21 [2.0] generics

22 [2.0] anon. methods

23 [2.0] iterators

24 [2.0] partial...
25 [2.0] nullable...

You might also like