03.01.2015 Views

Complete set: Intro to C - Bill Buchanan

Complete set: Intro to C - Bill Buchanan

Complete set: Intro to C - Bill Buchanan

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Name:<br />

Course: <strong>Intro</strong>duction <strong>to</strong> .NET<br />

Title: <strong>Intro</strong>duction<br />

Instruc<strong>to</strong>r: <strong>Bill</strong> <strong>Buchanan</strong><br />

.NET


1 <strong>Intro</strong>duction<br />

1.1 <strong>Intro</strong>duction<br />

The first module provides a basic introduction <strong>to</strong> the .NET. It covers:<br />

• <strong>Intro</strong>duction <strong>to</strong> Object‐orientation.<br />

• .NET Framework.<br />

• Visual Studio Environment.<br />

• Benefits of C# over VB.<br />

• .NET Components.<br />

• .NET Languages.<br />

.NET uses a newly developed language named C#, which has evolved through C++,<br />

and has adopted many of the object‐oriented ideas from Java.<br />

1.2 <strong>Intro</strong>duction <strong>to</strong> Object orientation<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

We live in a world full of objects; so object‐oriented programming is a natural technique<br />

in developing programs. For example, we have an object called a cup, and<br />

each cup has a number of properties, such as its colour, its shape, its size, and so on.<br />

It is efficient for us <strong>to</strong> identify it as a cup, as we know that cups should be able <strong>to</strong><br />

hold liquid, and we will place our cup beside all the other cups that we have. If we<br />

were a cup designer then we could list all the possible properties of a cup, and for<br />

each design, we could <strong>set</strong> the properties of the cup. Of course, some of the properties<br />

might not actually be used, but for a general‐purpose design, we would specify<br />

every property that a cup might have. For example, in a simple case we could have<br />

the following properties:<br />

Properties Cup 1 Cup 2 Cup3<br />

Shape (Standard/Square/Mug) Standard Square Mug<br />

Colour (Red/Blue/Green) Blue Red Green<br />

Size (Small/Medium/Large) Small Large Small<br />

Transparency (0 <strong>to</strong> 100%) 100% 50% 25%<br />

Handle type (Small/Large) Small Small Large<br />

Agilent .NET Course: <strong>Intro</strong>duction 2


Thus, we have three choices of shape (square, standard or mug), three choices of<br />

colour (red, blue or green), three choices in size (small, medium or large) and two<br />

choices of handle type (small or large). In addition, we can also choose a level of<br />

transparency of the cup from 0 <strong>to</strong> 100% (in integer steps). In object‐oriented program,<br />

the collection of properties is known as a class. Thus, we could have a class<br />

for our cup which encapsulates all the design parameters for our cup. The instance<br />

of our class, such as Cup 1, Cup 2 and Cup 3, are known as objects. We can create<br />

many objects from our class. Along with this, there are certain things that we want<br />

<strong>to</strong> do with the cup, such as picking it up, painting it, or even dropping it. In objec<strong>to</strong>rientation,<br />

these are known as methods, and are the functions that can be allowed<br />

<strong>to</strong> operate on our objects.<br />

Program 1.1 shows an object‐oriented example of the cup, where a class named<br />

Cup is created, of which an instance is named cup. A full description on this program<br />

will be discussed in a later module. It uses variables, such as Shape, Colour, and Size<br />

<strong>to</strong> define the property of an object.<br />

Program 1.1: Program1_1_ClassSimpleCup<br />

using System;<br />

namespace ConsoleApplication2<br />

{<br />

public class Cup<br />

{<br />

public string Shape;<br />

public string Colour;<br />

public string Size;<br />

public int Transparency;<br />

public string Handle;<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

public void DisplayCup()<br />

{<br />

System.Console.WriteLine("Cup is {0}, {1}", Colour, Handle);<br />

}<br />

}<br />

class Class1<br />

{<br />

static void Main(string[] args)<br />

{<br />

Cup cup = new Cup();<br />

cup.Colour = "Red"; cup.Handle = "Small";<br />

cup.DisplayCup();<br />

cup.Colour = "Green"; cup.Handle = "Small";<br />

cup.DisplayCup();<br />

System.Console.ReadLine();<br />

}<br />

}<br />

}<br />

Sample Run 1.1<br />

Cup is Red, Small<br />

Cup is Green, Small<br />

Agilent .NET Course: <strong>Intro</strong>duction 3


In the following example, we create a class named Circuit, of which we create a<br />

new instance of it named cir. The class then has two methods, named Serial and<br />

Parallel.<br />

Program 1.2: Program1_2_ClassSimpleResis<strong>to</strong>r<br />

using System;<br />

namespace ConsoleApplication2<br />

{<br />

public class Circuit<br />

{<br />

public string name;<br />

}<br />

public double Parallel(double r1, double r2)<br />

{<br />

return((r1*r2)/(r1+r2));<br />

}<br />

public double Series(double r1, double r2)<br />

{<br />

return(r1+r2);<br />

}<br />

class Class1<br />

{<br />

static void Main(string[] args)<br />

{<br />

double v1=100,v2=100;<br />

double res;<br />

Circuit cir = new Circuit();<br />

cir.name="Circuit 1";<br />

res=cir.Parallel(v1,v2);<br />

System.Console.WriteLine("[{0}] Parallel resistance is {1} ohms",<br />

cir.name,res);<br />

cir.name="Circuit 2";<br />

res=cir.Series(v1,v2);<br />

System.Console.WriteLine("[{0}] Series resistance is {1} ohms ",<br />

cir.name,res);<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

}<br />

}<br />

System.Console.ReadLine();<br />

Sample Run 1.2<br />

[Circuit 1] Parallel resistance is 50 ohms<br />

[Circuit 2] Series resistance is 200 ohms<br />

In this case, we have used a single object (cir). Of course, we could have created<br />

two objects, with:<br />

Circuit cir1 = new Circuit();<br />

Circuit cir2 = new Circuit();<br />

cir1.name="Circuit 1"; res1=cir1.Parallel(v1,v2);<br />

cir2.name="Circuit 2"; res2=cir.Series(v1,v2);<br />

Agilent .NET Course: <strong>Intro</strong>duction 4


Finally, for this section, Program 1.3 shows an example of a complex number class,<br />

where a complex number object is created (r), which is made up of two components<br />

(r.real and r.imag). The class defines two methods: mag() and angle(), which calculate<br />

the magnitude and the angle of the complex number, using:<br />

z = x + jy<br />

z<br />

z<br />

=<br />

x<br />

2<br />

= tan<br />

+ y<br />

−1<br />

⎛<br />

⎜<br />

⎝<br />

2<br />

y<br />

x<br />

⎞<br />

⎟<br />

⎠<br />

Program 1.3: Program1_3_ClassComplexNumberExample<br />

using System;<br />

namespace ConsoleApplication2<br />

{<br />

public class Complex<br />

{<br />

public double real;<br />

public double imag;<br />

public double mag()<br />

{<br />

return (Math.Sqrt(real*real+imag*imag));<br />

}<br />

public double angle()<br />

{<br />

return (Math.Atan(imag/real)*180/Math.PI);<br />

}<br />

}<br />

class Class1<br />

{<br />

static void Main(string[] args)<br />

{<br />

string str;<br />

double mag,angle;<br />

Complex r = new Complex();<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

}<br />

System.Console.Write("Enter real value >>");<br />

str=System.Console.ReadLine();<br />

r.real = Convert.ToInt32(str);<br />

System.Console.Write("Enter imag value >>");<br />

str=System.Console.ReadLine();<br />

r.imag = Convert.ToInt32(str);<br />

mag=r.mag();<br />

angle=r.angle();<br />

System.Console.WriteLine("Mag is {0} and angle is {1}",mag,angle);<br />

System.Console.ReadLine();<br />

}<br />

Sample Run 1.2<br />

Enter real value >> 3<br />

Enter imag value >> 4<br />

Mag is 5 and angle is 53.130102354156<br />

Agilent .NET Course: <strong>Intro</strong>duction 5


1.3 .NET Framework<br />

The PC has slowly evolved with ever‐increasing operating system components. Unfortunately,<br />

these additions make version control difficult. Microsoft has thus tried<br />

<strong>to</strong> overcome this by creating a common framework in which programs run. This<br />

framework should be easier <strong>to</strong> control and <strong>to</strong> update, where bug fixes can be updated<br />

with news downloads. Generally, Microsoft have further developed objec<strong>to</strong>rientation,<br />

and integrated many of the new techniques that Java created, such as<br />

operating system/hardware independence. They have also, for the first time, binded<br />

the .NET Framework <strong>to</strong> the Windows environment, which should improve security<br />

and allow enhanced integration with system components, such as using Microsoft<br />

Word as an edi<strong>to</strong>r, or Microsoft Excel <strong>to</strong> create and process spreadsheets.<br />

Figure 1.1 shows the typical steps taken in developing a program. Initially the<br />

source code is converted in<strong>to</strong> object code (OBJ) using a compiler. This converts the<br />

code in<strong>to</strong> a form which is matched <strong>to</strong> the hardware of the system, but cannot be run<br />

as it does not contain the basic elements of a program, such as routines which interface<br />

<strong>to</strong> the input/output. These elements are integrated with the linker, which takes<br />

all the created object code files, and searches in the static libraries for any code that<br />

is required <strong>to</strong> produce the executable program. The program can then access system<br />

routing through API (Application Programming Interface) calls, such as in creating<br />

Windows, or interfacing <strong>to</strong> networking functions. These API calls are typically contained<br />

in run‐time libraries (DLL’s), which contain the code which implements the<br />

require function.<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Source<br />

Code<br />

(C/C++/<br />

Delphi/<br />

VB)<br />

Compilation<br />

OBJ file<br />

Static Static<br />

Libraries<br />

Linker Linker<br />

gdi32.dll<br />

EXE EXE<br />

Program Program<br />

API<br />

(Application<br />

Programming<br />

Interface)<br />

ole32.dll<br />

Figure 1.1: Traditional stages of program development<br />

Agilent .NET Course: <strong>Intro</strong>duction 6


1.3.1 Win32 API<br />

The Win32 API library contains many routines:<br />

• Creating windows.<br />

• Windows support functions.<br />

• Message processing.<br />

• Menus.<br />

• Resources.<br />

• Dialog boxes.<br />

• User input functions.<br />

• Memory management.<br />

• GDI (graphical device interface).<br />

• Bitmaps, icons and metafiles.<br />

• Printing and text output.<br />

• Painting and drawing.<br />

• File I/O.<br />

• Clipboard. Support for public and<br />

private clipboards.<br />

• Registry. Support for functions<br />

which access the Registry.<br />

• Initialization files. Support for<br />

functions which access INI files.<br />

• System information.<br />

• String manipulation.<br />

• Timers.<br />

• Processes and threads.<br />

• Error and exception processing.<br />

• Help files.<br />

• File compression/decompression.<br />

• DLLs.<br />

• Network support (NetBios and<br />

Windows sockets 1.1 APIs).<br />

• Multimedia support (sound<br />

APIs).<br />

• OLE and DDE (dynamic data exchange).<br />

• TrueType fonts.<br />

An example of a C++ call <strong>to</strong> these APIs is:<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Program 1.4: ClassComplexNumberExample<br />

#include <br />

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmd, int nShow)<br />

{<br />

char msg[128];<br />

wsprintf(msg, "My name is Fred");<br />

MessageBox(GetFocus(), msg, "My first Window", MB_OK | MB_ICONINFORMATION);<br />

return(0);<br />

}<br />

Where the MessageBox() routine is a standard API call <strong>to</strong> show a basic message box,<br />

such as:<br />

Agilent .NET Course: <strong>Intro</strong>duction 7


1.3.2 .NET Enhancements<br />

Software development for the PC has developed through the use of languages such<br />

as C++, Delphi and Visual Basic. These languages are all focused on producing Windows‐based<br />

programs using the x86 architecture. The computing industry, though,<br />

has moved over the last few years, with the advent of the Internet and Java. With<br />

Java, Sun Microsystems have tried <strong>to</strong> produce programs which could be run on any<br />

type of hardware. This has the advantage that the program can be produced for a<br />

range of hardware, including Apple‐based computers and hand‐held devices. There<br />

has also been a move <strong>to</strong>ward using software routines which are not necessarily<br />

based on the host computer, and in integrating WWW services with programs. This<br />

integration is illustrated in Figure 1.2.<br />

In general the current weaknesses of software development which have been<br />

overcome with .NET are:<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

• Lack of support for different hardware. .NET overcomes this in a similar way<br />

<strong>to</strong> Java in that it produces an intermediate code known as MSIL (Microsoft Intermediate<br />

Language) which when run with the CLR (Common Language<br />

Runtime) produces an executable program which matches the hardware.<br />

• Difficult <strong>to</strong> integrate different programming languages. This is a problem with<br />

most software development environments, especially in representing the variables<br />

in the same way. .NET overcomes this by producing a standardized<br />

system for data representation, known as CTS (Common Type Representation).<br />

The compiler also uses CLS (Common Language Specification) <strong>to</strong> produce code<br />

which can be integrated with other programming languages. Along with this the<br />

.NET framework uses a FCL (Framework Class Library) which is a common <strong>set</strong><br />

of classes which can be used with the different languages.<br />

• Lack of security integration. .NET binds itself with the operating system so that<br />

it integrates better with the security controls of the system.<br />

• Poor version control of system components. .NET improves this by supporting<br />

the installation of different versions of the .NET framework. Users can choose<br />

which of the version they install, and previous versions will be s<strong>to</strong>red on the<br />

host.<br />

• Weak integration with the WWW/Internet. .NET integrates WWW development<br />

with code development by integrating ASP with VB/C#.<br />

In order <strong>to</strong> support these advancements, Microsoft has developed Visual Basic further<br />

and integrated it with ASP, <strong>to</strong> produce VB.NET. C++ has also been advanced <strong>to</strong><br />

C# which incorporates many of the advanced features of Java. Figure 1.3 outlines<br />

some of the key features of the .NET framework.<br />

Agilent .NET Course: <strong>Intro</strong>duction 8


VB VB<br />

ASP ASP<br />

ASP ASP<br />

VBA VBA<br />

VB VB .NET .NET<br />

C# C#<br />

Executable Executable<br />

Program Program<br />

Visual Studio<br />

C C<br />

C++ C++<br />

ASP<br />

WWW<br />

Services<br />

COM+<br />

(Distributed<br />

Components)<br />

.NET Platform<br />

API<br />

(Application<br />

Programming<br />

Interface)<br />

Figure 1.2: .NET Integration<br />

VB VB .NET .NET<br />

C# C#<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

CTS<br />

CTS<br />

(Common<br />

(Common<br />

Type<br />

Type<br />

System)<br />

System)<br />

FCL FCL<br />

(Framework<br />

Class Class Library)<br />

Web<br />

Web<br />

component<br />

component<br />

Compiler<br />

MSIL (Microsoft<br />

Intermediate Language)<br />

CLS<br />

CLS<br />

(Common<br />

(Common<br />

Language<br />

Language<br />

Specification)<br />

Specification)<br />

CLR CLR (Common Language Runtime)<br />

Allows Allows the the programs <strong>to</strong> <strong>to</strong> run run – similar similar <strong>to</strong> <strong>to</strong> the the Java Java Virtual Virtual Machine (JVM) (JVM)<br />

Figure 1.3: .NET Framework<br />

Agilent .NET Course: <strong>Intro</strong>duction 9


1.3.3 .NET Environment<br />

DLL’s are typically installed in the system folders of the host. It is thus difficult <strong>to</strong><br />

keep track of new updates which enhance features or <strong>to</strong> fix bugs, as system files<br />

where often overwritten by new ones. One method that was used <strong>to</strong> support these<br />

updates was Direct X, which allowed software components <strong>to</strong> be registered on<strong>to</strong> a<br />

system (Figure 1.4). Thus, when a program required a service, such as network support,<br />

it would call the required DLL.<br />

The problem of version control has now been reduced using the .NET framework.<br />

With this the key framework files are installed <strong>to</strong> a single folder. An example<br />

of this is shown in Figure 1.5. It can be seen that the single folder makes it easier <strong>to</strong><br />

update with new versions. A key DLL is the Mscorlib.dll which contains many of<br />

the key elements of the .NET framework, such as for file I/O, system interfacing and<br />

security.<br />

Figure 1.4: DLL registration<br />

1.4 Visual Studio .NET Environment<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

The Visual Studio .NET Environment provides an integration of the Visual Studio<br />

environment with new features, especially in au<strong>to</strong>mated code generation, and intelligent<br />

sensing of user requirements. It uses projects (VBP) or solutions (SLN) <strong>to</strong><br />

create folders which contains the required elements of the program. In creating a<br />

new project (with FileNewProject), the user is then asked for the required application<br />

(Figure 1.6). This include a C# or a VB project. Once selected the user then<br />

selects a template for the project, such as:<br />

• Console application. This uses a command line window for the output, and is<br />

useful in applications which require text‐based information.<br />

• Windows application. This uses type of application uses Windows for its interface,<br />

such as with text boxes and menus.<br />

Agilent .NET Course: <strong>Intro</strong>duction 10


Volume in drive C has no label.<br />

Volume Serial Number is 1A83-0D9D<br />

Direc<strong>to</strong>ry of C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322<br />

21/02/2003 08:24 7,680 Accessibility.dll<br />

21/02/2003 06:00 98,304 alink.dll<br />

20/02/2003 20:19 24,576 aspnet_filter.dll<br />

20/02/2003 20:19 253,952 aspnet_isapi.dll<br />

20/02/2003 20:19 40,960 aspnet_rc.dll<br />

20/02/2003 20:09 77,824 CORPerfMonExt.dll<br />

21/02/2003 11:21 626,688 cscomp.dll<br />

21/02/2003 08:24 12,288 cscompmgd.dll<br />

21/02/2003 08:24 33,792 Cus<strong>to</strong>mMarshalers.dll<br />

29/07/2002 12:11 219,136 c_g18030.dll<br />

21/02/2003 11:21 524,288 diasymreader.dll<br />

19/03/2003 02:52 245,760 envdte.dll<br />

20/02/2003 20:16 798,720 EventLogMessages.dll<br />

20/02/2003 20:06 282,624 fusion.dll<br />

21/02/2003 08:24 7,168 IEExecRemote.dll<br />

21/02/2003 08:24 32,768 IEHost.dll<br />

21/02/2003 08:24 4,608 IIEHost.dll<br />

21/02/2003 08:25 1,564,672 mscorcfg.dll<br />

20/02/2003 20:09 77,824 mscordbc.dll<br />

20/02/2003 20:09 233,472 mscordbi.dll<br />

20/02/2003 20:09 86,016 mscorie.dll<br />

20/02/2003 20:06 311,296 mscorjit.dll<br />

20/02/2003 20:09 98,304 mscorld.dll<br />

21/02/2003 08:26 2,088,960 mscorlib.dll<br />

20/02/2003 19:43 131,072 mscormmc.dll<br />

20/02/2003 20:06 65,536 mscorpe.dll<br />

20/02/2003 20:09 143,360 mscorrc.dll<br />

20/02/2003 20:09 81,920 mscorsec.dll<br />

20/02/2003 20:09 77,824 mscorsn.dll<br />

20/02/2003 20:07 2,494,464 mscorsvr.dll<br />

20/02/2003 20:09 9,216 mscortim.dll<br />

20/02/2003 20:08 2,482,176 mscorwks.dll<br />

21/02/2003 05:42 348,160 msvcr71.dll<br />

18/03/2003 20:03 544,768 msvcr71d.dll<br />

20/02/2003 20:18 20,480 mtxoci8.dll<br />

19/03/2003 02:50 196,608 office.dll<br />

20/02/2003 20:09 90,112 PerfCounter.dll<br />

21/02/2003 08:26 32,768 RegCode.dll<br />

Program<br />

Contains most of the code<br />

that is called by the program<br />

Mscorlib.dll<br />

Arrays,<br />

Arrays,<br />

File<br />

File<br />

I/O,<br />

I/O,<br />

System,<br />

System,<br />

Security<br />

Security<br />

Figure 1.5: .NET framework installation folder<br />

Name of the folder<br />

Which contains the<br />

Project files<br />

the project is s<strong>to</strong>red.<br />

Folder where<br />

the project is s<strong>to</strong>red.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Figure 1.6: Creating a project<br />

Figure 1.7 shows an example of the Visual Studio C# .NET environment. The project<br />

elements are s<strong>to</strong>red in the Solution explorer window. The actual code is displayed in<br />

the Code and Text Edi<strong>to</strong>r window. For C# programs, the file name has a .cs extension.<br />

A useful feature of the environment is the edi<strong>to</strong>r’s statement completion which<br />

aids the developer by completing the required statement, as well as given help on<br />

its syntax.<br />

Agilent .NET Course: <strong>Intro</strong>duction 11


1.4.1 Solution files<br />

The solution file contains of the required elements of a project. The information is<br />

contained in an sln file. In Figure 1.9, the solution file is named Module01_01.sln,<br />

will the contents of the file is displayed in Figure 1.9. It can be seen that it defines<br />

the environment of the development system, and defines a project file, which is defined<br />

with a csproj file extension. In this case, the project file is named<br />

Module01_01.csproj. The project file contains the references <strong>to</strong> all the required files<br />

that the solution uses. In this case, as shown in Figure 1.10, the files used are<br />

App.ico, AssemblyInfo.cs and Class1.cs. The C# code is contained in cs files, which<br />

are known as class files.<br />

Class file (.cs)<br />

Solution explorer<br />

Code and<br />

Text Edi<strong>to</strong>r<br />

Edi<strong>to</strong>r's statement<br />

completion<br />

Figure 1.7: Visual Studio C# .NET environment<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Figure 1.8: Example listing<br />

Agilent .NET Course: <strong>Intro</strong>duction 12


Module01_01.sln<br />

Module01_01.sln<br />

Microsoft Visual Studio Solution File, Format Version 8.00<br />

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}")<br />

Microsoft Visual Studio Solution File, Format Version<br />

= "Module01_01",<br />

8.00<br />

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}")<br />

"Module01_01.csproj", "{1EA384DD-927E-4B94-ABB8-BA08DFAE5AB3}"<br />

= "Module01_01",<br />

ProjectSection(ProjectDependencies)<br />

"Module01_01.csproj", "{1EA384DD-927E-4B94-ABB8-BA08DFAE5AB3}"<br />

= postProject<br />

EndProjectSection<br />

ProjectSection(ProjectDependencies) = postProject<br />

EndProject<br />

EndProjectSection<br />

Global<br />

EndProject<br />

Global<br />

GlobalSection(SolutionConfiguration) = preSolution<br />

GlobalSection(SolutionConfiguration)<br />

Debug = Debug<br />

= preSolution<br />

Release<br />

Debug =<br />

=<br />

Debug<br />

Release<br />

EndGlobalSection<br />

Release = Release<br />

GlobalSection(ProjectConfiguration)<br />

EndGlobalSection<br />

= postSolution<br />

GlobalSection(ProjectConfiguration)<br />

{1EA384DD-927E-4B94-ABB8-BA08DFAE5AB3}.Debug.ActiveCfg<br />

= postSolution<br />

=<br />

Debug|.NET<br />

{1EA384DD-927E-4B94-ABB8-BA08DFAE5AB3}.Debug.ActiveCfg =<br />

Debug|.NET<br />

{1EA384DD-927E-4B94-ABB8-BA08DFAE5AB3}.Debug.Build.0 =<br />

Debug|.NET<br />

{1EA384DD-927E-4B94-ABB8-BA08DFAE5AB3}.Debug.Build.0 =<br />

Debug|.NET<br />

{1EA384DD-927E-4B94-ABB8-BA08DFAE5AB3}.Release.ActiveCfg =<br />

Release|.NET<br />

{1EA384DD-927E-4B94-ABB8-BA08DFAE5AB3}.Release.ActiveCfg =<br />

Release|.NET<br />

{1EA384DD-927E-4B94-ABB8-BA08DFAE5AB3}.Release.Build.0 =<br />

Release|.NET<br />

{1EA384DD-927E-4B94-ABB8-BA08DFAE5AB3}.Release.Build.0 =<br />

EndGlobalSection<br />

Release|.NET<br />

GlobalSection(ExtensibilityGlobals)<br />

EndGlobalSection<br />

= postSolution<br />

EndGlobalSection<br />

GlobalSection(ExtensibilityGlobals) = postSolution<br />

GlobalSection(ExtensibilityAddIns)<br />

EndGlobalSection<br />

= postSolution<br />

EndGlobalSection<br />

GlobalSection(ExtensibilityAddIns) = postSolution<br />

EndGlobal<br />

EndGlobalSection<br />

EndGlobal<br />

Figure 1.9: Example sln file<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Module01_01.csprof<br />

Module01_01.csprof<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

/><br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

SubType = "Code"<br />

<br />

<br />

<br />

BuildAction = "Compile" /><br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Figure 1.10: Project file<br />

Agilent .NET Course: <strong>Intro</strong>duction 13


Class1.cs<br />

Class1.cs<br />

using System;<br />

using System;<br />

namespace Module01_01<br />

namespace Module01_01<br />

{<br />

{<br />

/// <br />

/// <br />

/// Summary description for Class1.<br />

/// Summary description for Class1.<br />

/// <br />

/// <br />

class Class1<br />

class Class1<br />

{<br />

{<br />

/// <br />

/// <br />

/// The main entry point for the application.<br />

/// The main entry point for the application.<br />

/// <br />

/// <br />

static void Main(string[] args)<br />

static void Main(string[] args)<br />

{<br />

{<br />

//<br />

//<br />

// TODO: Add code <strong>to</strong> start application here<br />

// TODO: Add code <strong>to</strong> start application here<br />

System.Console.WriteLine("Agilent<br />

System.Console.WriteLine("Agilent<br />

Course");<br />

Course");<br />

System.Console.ReadLine();<br />

System.Console.ReadLine();<br />

}<br />

}<br />

}<br />

}<br />

}<br />

}<br />

Figure 1.11: CS file<br />

Along with this, most projects contain an AssemblyInfo class file, an example of<br />

which is shown in Figure 1.12. .NET uses assembly <strong>to</strong> represent a single unit. An<br />

assembly, <strong>to</strong> be covered in a future unit, is a collection of files that appear as a single<br />

unit, such as a single DLL or an EXE. Along with class files, most projects contain an<br />

icon file, which is associated with the executable program. An example of an icon is<br />

shown in Figure 1.13.<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

AssemblyInfo.cs<br />

AssemblyInfo.cs<br />

using System.Reflection;<br />

using<br />

using<br />

System.Runtime.CompilerServices;<br />

System.Reflection;<br />

using System.Runtime.CompilerServices;<br />

//<br />

//<br />

//<br />

General Information about an assembly is controlled through the following<br />

//<br />

//<br />

<strong>set</strong><br />

General<br />

of attributes.<br />

Information<br />

Change<br />

about<br />

these<br />

an assembly<br />

attribute<br />

is<br />

values<br />

controlled<br />

<strong>to</strong> modify<br />

through<br />

the<br />

the<br />

information<br />

following<br />

//<br />

//<br />

associated<br />

<strong>set</strong> of attributes.<br />

with an assembly.<br />

Change these attribute values <strong>to</strong> modify the information<br />

//<br />

// associated with an assembly.<br />

[assembly:<br />

//<br />

AssemblyTitle("")]<br />

[assembly:<br />

[assembly:<br />

AssemblyDescription("")]<br />

AssemblyTitle("")]<br />

[assembly:<br />

[assembly:<br />

AssemblyConfiguration("")]<br />

AssemblyDescription("")]<br />

[assembly:<br />

[assembly:<br />

AssemblyCompany("")]<br />

AssemblyConfiguration("")]<br />

[assembly:<br />

[assembly:<br />

AssemblyProduct("")]<br />

AssemblyCompany("")]<br />

[assembly:<br />

[assembly:<br />

AssemblyCopyright("")]<br />

AssemblyProduct("")]<br />

[assembly:<br />

[assembly:<br />

AssemblyTrademark("")]<br />

AssemblyCopyright("")]<br />

[assembly:<br />

[assembly:<br />

AssemblyCulture("")]<br />

AssemblyTrademark("")]<br />

[assembly: AssemblyCulture("")]<br />

//<br />

//<br />

//<br />

Version information for an assembly consists of the following four values:<br />

//<br />

// Version information for an assembly consists of the following four values:<br />

//<br />

//<br />

Major Version<br />

//<br />

//<br />

Minor<br />

Major<br />

Version<br />

Version<br />

//<br />

//<br />

Build<br />

Minor<br />

Number<br />

Version<br />

//<br />

//<br />

Revision<br />

Build Number<br />

//<br />

// Revision<br />

//<br />

//<br />

You can specify all the values or you can default the Revision and Build<br />

// You<br />

Numbers<br />

can specify all the values or you can default the Revision and Build<br />

// by using<br />

Numbers<br />

the '*' as shown below:<br />

// by using the '*' as shown below:<br />

[assembly: AssemblyVersion("1.0.*")]<br />

[assembly: AssemblyVersion("1.0.*")]<br />

[assembly: AssemblyDelaySign(false)]<br />

[assembly:<br />

[assembly:<br />

AssemblyKeyFile("")]<br />

AssemblyDelaySign(false)]<br />

[assembly:<br />

[assembly:<br />

AssemblyKeyName("")]}<br />

AssemblyKeyFile("")]<br />

[assembly: AssemblyKeyName("")]}<br />

Figure 1.12: AssemblyInfo class file<br />

Agilent .NET Course: <strong>Intro</strong>duction 14


1.4.2 Using the environment<br />

Figure 1.13: Icon file<br />

The C# code is displayed in the Edi<strong>to</strong>r windows, as illustrated in Figure 1.14. The<br />

classes within the file are displayed within the Types pull down menu item. It can<br />

be seen, that, in this case, that the classes are named:<br />

• ConsoleApplication2.ArrayExample02().<br />

• ConsoleApplication2.test().<br />

These are defined with the namespace of ConsoleApplication2 (namespaces will be<br />

covered in a following section). Once within the class the members of the class are<br />

shown in the right‐hand pull down menu. The main graphics used <strong>to</strong> display the<br />

members are:<br />

‐ Method within a class. If it has a padlock, it is a private method.<br />

‐ Variable within a class. If it has a padlock, it is a private variable.<br />

‐ Property of a class. Figure 1.15 shows an example of this.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Figure 1.14: Types<br />

Types<br />

Agilent .NET Course: <strong>Intro</strong>duction 15


Methods Variable<br />

1.4.3 Viewing objects<br />

Figure 1.15: Class members<br />

Along with viewing the classes, it is possible <strong>to</strong> view the complete hierarchy of the<br />

objects in the solution. This includes the hierarchy above the classes that have been<br />

developed. Figure 1.16 shows an example of the object browser, and Figure 1.17<br />

shows the browsing of the objects within the core library (mscorlib). In this case it<br />

shows the objects within Systems.Collections.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Figure 1.16: Object browsing<br />

Agilent .NET Course: <strong>Intro</strong>duction 16


Figure 1.17: Object browsing for other classes<br />

1.5 .NET Languages<br />

The two main languages of .NET are VB.NET and C#. Example of their syntax are<br />

shown in Program 1.5 and 1.6. The gulf between VB and C++ was, at one time, a<br />

massive one, as C++ contained more error checking and had a strong syntax. With<br />

the advent of VB.NET, the gulf between VB and the new version of C++ (C#) has reduced.<br />

Both are fully object‐oriented, and the weaknesses of VB have now been<br />

overcome. The true strength of C# is its simple and precise syntax which many professional<br />

developers prefer <strong>to</strong> VB.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Program 1.5: Program1_5_ExampleOfVBCodePrimeNumberGeneration<br />

‘ VB.NET Code<br />

Dim j As Integer<br />

Dim prime As Boolean<br />

Dim i As Integer<br />

For i = 1 To 100<br />

prime = True<br />

For j = 2 To (i / 2)<br />

If ((i Mod j) = 0) Then<br />

prime = False<br />

End If<br />

Next j<br />

If (prime = True) Then<br />

TextBox1.Text = TextBox1.Text & "," & Str(i)<br />

End If<br />

Next i<br />

Sample Run 1.5<br />

1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79,<br />

83, 89, 97<br />

Agilent .NET Course: <strong>Intro</strong>duction 17


Program 1.6: Program1_6_ExampleOfC#CodePrimeNumberGeneration<br />

// C# Code<br />

int i, j;<br />

bool prime;<br />

for (i=0;i


1.6 Basic elements of a C# program<br />

C# follows its parents in having a minimal number of keywords. These are:<br />

abstract event new struct<br />

as explicit null switch<br />

base extern object this<br />

bool false opera<strong>to</strong>r throw<br />

break finally out true<br />

byte fixed override try<br />

case float params typeof<br />

catch for private uint<br />

char foreach protected ulong<br />

checked go<strong>to</strong> public unchecked<br />

class if readonly unsafe<br />

const implicit ref ushort<br />

continue in return using<br />

decimal int sbyte virtual<br />

default interface sealed volatile<br />

delegate internal short void<br />

do is sizeof while<br />

double lock stackalloc<br />

else long static<br />

enum namespace string<br />

C#, as the other C languages is case sensitive, thus the keywords must use the lowercase<br />

format. The main elements of a C# program are given next.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

using System;<br />

namespace ConsoleApplication2<br />

{<br />

public class Complex<br />

{<br />

public double real;<br />

public double imag;<br />

}<br />

public int val { <strong>set</strong> {} get {} };<br />

public double mag()<br />

{<br />

return (Math.Sqrt(real*real+imag*imag));<br />

}<br />

public double angle()<br />

{<br />

return (Math.Atan(imag/real)*180/Math.PI);<br />

}<br />

using. Imports types defined<br />

in other namespaces.<br />

namespace. Defines a unique<br />

name for the objects. In this case<br />

the objects would have the name<br />

of:<br />

ConsoleApplications2.Complex()<br />

ConsoleApplicai<strong>to</strong>ns2.Class1()<br />

Agilent .NET Course: <strong>Intro</strong>duction 19


class Class1<br />

{<br />

static void Main(string[] args)<br />

{<br />

Complex r = new Complex();<br />

string str;<br />

double mag,angle;<br />

System.Console.Write("Enter real value >> ");<br />

str=System.Console.ReadLine();<br />

r.real = Convert.ToInt32(str);<br />

System.Console.Write("Enter imag value >> ");<br />

str=System.Console.ReadLine();<br />

r.imag = Convert.ToInt32(str);<br />

Main(). This is the<br />

entry point in<strong>to</strong> the<br />

program, and defines<br />

the start and<br />

end of the program.<br />

It must be declared<br />

inside a class, and<br />

must be static.<br />

mag=r.mag();<br />

angle=r.angle();<br />

System.Console.WriteLine("Mag is {0} and angle is {1}",mag,angle);<br />

}<br />

}<br />

}<br />

System.Console.ReadLine();<br />

1.6.1 Namespace<br />

For the namespace, the full name of the Complex() class, its full name would be:<br />

ConsoleApplication2.Complex()<br />

Thus we could have used:<br />

ConsoleApplication2.Complex r = new ConsoleApplication2.Complex()<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

but as we are in the same namespace it is possible <strong>to</strong> use the relative form.<br />

1.6.2 using<br />

The using keyword is used imports types from other namespaces. Figure 1.18 shows<br />

types that are imported for System.Console.Writeln(). It is important <strong>to</strong> import the<br />

required namespace for the classes that are required. Examples include:<br />

System:<br />

System.Collections:<br />

System.IO:<br />

Array, Boolean, Byte, Char, Convert, DateTime, Double,<br />

Enum, Int16, Int32, Int64, Math, Random, String, Void<br />

ArrayList, BitArray, Hashtable, Queue, Stack.<br />

BinaryReader, BinaryWriter, File, Stream, StreamWriter,<br />

StreamReader<br />

Agilent .NET Course: <strong>Intro</strong>duction 20


System.Console.Write("Enter real value >> ");<br />

Figure 1.18: System namespace<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: <strong>Intro</strong>duction 21


Name:<br />

Course: <strong>Intro</strong>duction <strong>to</strong> .NET<br />

Title: Module 2 Basics of C#<br />

Instruc<strong>to</strong>r: Andrew Cumming<br />

.NET


2 Module 2 Basics of C#<br />

2.1 <strong>Intro</strong>duction<br />

Afternoon session<br />

• Using types and variables.<br />

• Statements ‐ for, while and if.<br />

• File handling.<br />

• <strong>Intro</strong>ducing methods and parameters<br />

Tu<strong>to</strong>rial<br />

• Boxes<br />

• CIA Data<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: C# Basics 2


2.2 Types<br />

The language C# is strongly typed. This means that a compile time error occurs if<br />

we make a type error.<br />

Some basic types are:<br />

Type Example Notes<br />

int ‐100 32‐bit<br />

char ‘x’ Uni‐code<br />

string “Andrew was here.” Strings are double quoted.<br />

Object new String(‘a’,10) Object is the most general type of object.<br />

Variables are declared by giving the type followed by the name of the variable. In<br />

these examples the variables are declared and given an initial value in the same line.<br />

Sample program fragment<br />

char c = 'x';<br />

string s = "Andrew was here.";<br />

int i = -100;<br />

double d = 3.1415;<br />

Object s = new System.IO.StreamReader("file.txt");<br />

Object h = new System.Collections.Hashtable();<br />

.<br />

2.3 Type Casting<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

A type cast can be used <strong>to</strong> convert one type <strong>to</strong> another.<br />

The cast may be either explicit of implicit.<br />

Sample program fragment<br />

char c0 = 'A';<br />

int i0 = c0; // Implicit cast works<br />

//string s0 = c; // This fails<br />

//string s1 = (string) c; // This fails<br />

string s2 = "A" + c0; // This succeeds<br />

double d0 = i0;<br />

float f0 = (float)d0;<br />

//float f1 = d0; // This fails<br />

int i1 = (int)d0;<br />

//int i1 = d0; // This fails<br />

int i2 = (int)c0;<br />

Agilent .NET Course: C# Basics 3


2.4 Casting Objects<br />

Sometimes we need <strong>to</strong> cast objects.<br />

We may cast up or down the object hierarchy.<br />

Casting down is dangerous and may result in a run time error.<br />

Examples of casting Objects<br />

Object sr0 = new StreamReader("file.txt");<br />

Object ht0 = new Hashtable();<br />

// Following fails at compile time<br />

// StreamReader f1 = sr0;<br />

StreamReader f2 = (StreamReader)sr0;<br />

// Following generates run time error<br />

StreamReader f3 = (StreamReader)ht0;<br />

2.4.1 Self-test<br />

For each of the following decide if the line will work OK or fail at design time or fail<br />

at run time.<br />

Which of these will compile and run<br />

int i0 = 3.1;<br />

string s0 = 'x';<br />

char c0 = 'c';<br />

string s1 = "x" + 'y';<br />

char c1 = (char) "a";<br />

float f0 = 3;<br />

Compile Error<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

float f1 = "3.1";<br />

DateTime v0 = DateTime.Now;<br />

Object v1 = DateTime.Now;<br />

Object v2 = new Object();<br />

DateTime v3 = (DateTime) new Object();<br />

DateTime v4 = new Object();<br />

OK<br />

OK<br />

Agilent .NET Course: C# Basics 4


2.5 Converting between types<br />

A cast does not involve processing ‐ data is simply interpreted in a different way.<br />

For example if we cast the character ʹ5ʹ <strong>to</strong> an integer we get the ASCII code for 5<br />

(which is 53).<br />

A conversion usually involves some processing.<br />

2.5.1 Converting <strong>to</strong> a string<br />

We often need <strong>to</strong> convert <strong>to</strong> a string.<br />

2.5.1.1 ToString()<br />

The method ToString() can be used for any object. We may optionally control the<br />

format with a format string.<br />

Examples of ToString on an integer<br />

//No surprises here – it gives "3"<br />

3.ToString();<br />

//The stand currency format is used "£3.00" for the UK<br />

3.ToString("c");<br />

//Uses three digits both sides of the . "003.000"<br />

3.ToString("000.000");<br />

//Daisy chains a string method " 3"<br />

3.ToString().PadLeft(5)<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

2.5.1.2 String.Format()<br />

The Format method of the String class may be used <strong>to</strong> construct strings with variable<br />

components.<br />

Examples of use:<br />

Examples of String.Format<br />

// {0} is a place holder "3 men went <strong>to</strong> mow"<br />

String.Format("{0} men went <strong>to</strong> mow.",3)<br />

//"The time is now 23/06/04 12:30"<br />

String.Format("The time now is {0}.", DateTime.Now)<br />

//The place holder {1} crops up with different formats<br />

String.Format("I paid {0:c} on {1:%d} of {1:%MMM}.",<br />

3,DateTime.Now));<br />

In a string format {0} indicates the first parameter, {1} is the next…<br />

Following this indica<strong>to</strong>r we can specify the format <strong>to</strong> be used after a :<br />

In the example above :c indicates currency ‐ £3.00.<br />

Agilent .NET Course: C# Basics 5


2.6 The Convert class<br />

The convert class includes many methods that may be used <strong>to</strong> convert from one<br />

data type <strong>to</strong> another:<br />

There are other mechanisms from translating. Some classes have a Parse method.<br />

2.6.1 Exercises:<br />

Set the following variables:<br />

Variables <strong>to</strong> be used in the exercise<br />

int i = 99;<br />

DateTime w = Convert.ToDateTime("21 Jun 2004 12:30");<br />

double d = 42.3;<br />

Use these values as input <strong>to</strong> one String.Format or ToString <strong>to</strong> produce each of the<br />

following:<br />

1 Use i <strong>to</strong> produce ʺ0099ʺ<br />

i.ToString(ʺ0000ʺ)<br />

2 Use w <strong>to</strong> produce ʺ21/06/2004 12:30:00ʺ – The default local date format.<br />

3 Use w <strong>to</strong> produce ʺMondayʺ ‐ The day of the week.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

4 Use d <strong>to</strong> produce ʺ42.300ʺ ‐ To exactly 3 decimal places.<br />

5 Use i <strong>to</strong> produce 63 – The hex value of 99<br />

Agilent .NET Course: C# Basics 6


2.7 Summary<br />

The base types include<br />

• char<br />

• string<br />

• int<br />

• double<br />

The Framework Class Library includes many other classes such as<br />

• DateTime<br />

• StreamReader<br />

• HashTable<br />

• Object<br />

Variable declaration<br />

• Variable may be declared with different scope.<br />

• A typical declaration includes the type or class name followed by the variable<br />

name.<br />

• The declaration may include an initial value.<br />

• Constants may be declared in a similar way ‐ the modifier const precedes the<br />

type.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Strings<br />

• Strings literals have double quotes.<br />

• Normally \ introduces codes ‐ for example \n and \t for new line and tab. For<br />

file names we must escape the backslash ʺc:\\dir\\file.txtʺ<br />

• A string literal preceded by @ prevents the backslash escape mechanism. We<br />

can have line breaks in strings. File names may be simpler @ʺc:\dir\file.txtʺ<br />

Converting <strong>to</strong> a string<br />

• We may use String.Format<br />

• We may use .ToString()<br />

• Format codes may be used <strong>to</strong> dictate the way values are rendered.<br />

Agilent .NET Course: C# Basics 7


2.7.1 Examples of output of the DateTime<br />

Using the DateTime: 2 March 2004 05:06<br />

{0:%d} 2<br />

{0:dd} 02<br />

{0:ddd} Tue<br />

{0:dddd} Tuesday<br />

{0:%m} 6<br />

{0:mm} 06<br />

{0:%M} 3<br />

{0:MM} 03<br />

{0:MMM} Mar<br />

{0:MMMM} March<br />

2.7.2 Help is available with the following headings<br />

The standard and cus<strong>to</strong>m fpormats are explained in greater details in the help system.<br />

They can be difficult <strong>to</strong> track down.<br />

• Standard numeric format strings<br />

• Cus<strong>to</strong>m numeric format strings<br />

• Standard DateTime format strings<br />

• Cus<strong>to</strong>m DateTime format strings<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: C# Basics 8


2.8 Statements<br />

The language C# includes statements for iteration and selection.<br />

The for statement has three components in addition <strong>to</strong> the body.<br />

Commonly the control variable in a for loop is declared as local <strong>to</strong> the loop.<br />

A for loop – table of squares<br />

for (int i = 1; i


2.9 StreamReader<br />

The StreamReader class allows us <strong>to</strong> access data from files.<br />

Useful methods of StreamReader:<br />

• ReadLine() returns one line as a string<br />

• Read() returns the ASCII for the next character and consumes it.<br />

• Peek() returns the ASCII for the next character without consuming it.<br />

When we hit the end of file Peek() returns –1 – this is useful <strong>to</strong> control a while loop<br />

(although not as useful as EOF would have been).<br />

A while loop <strong>to</strong> print the first non-space character of every line<br />

System.IO.StreamReader fh =<br />

new System.IO.StreamReader(@"..\..\Form1.cs");<br />

while (fh.Peek() != -1)<br />

{<br />

string ln = fh.ReadLine().TrimStart();<br />

if (ln.Length>0)<br />

Console.WriteLine(ln[0]);<br />

}<br />

MessageBox.Show("Done!");<br />

Notes:<br />

• StreamReader is in the System.IO namespace<br />

• ln.Length returns the length of a string<br />

• ln[0] gives the first character of the string ln. We get a run time error if the<br />

string is <strong>to</strong>o short.<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: C# Basics 10


2.10 Boxes tu<strong>to</strong>rial<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Horizontal Stripes<br />

private void HorizStripes_Click(object sender, System.EventArgs e)<br />

{<br />

for (int i=0;i


2.11 CIA tu<strong>to</strong>rial (1)<br />

In this tu<strong>to</strong>rial we read the file ciaFixedWidth.txt<br />

This file lists all coutries of the world, it gives their name, the region, the area in<br />

km 2 , the population and the GDP in US dollars.<br />

The strings name and region are in 50 characters each. The three numbers, area,<br />

population and gdp are in 20 characters each.<br />

Character positions…<br />

0 50 100 120 140<br />

Afghanistan Asia 647500 21251821 18100000000<br />

Algeria Africa 2381740 28539321 97100000000<br />

The first but<strong>to</strong>n includes code <strong>to</strong> read a single line of the file.<br />

For the following questions we suggest that you read the entire file for each question.<br />

Each of the further but<strong>to</strong>ns is should report the answer as a message box:<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

1 Find France – show all the details of France<br />

2 Count countries – return the <strong>to</strong>tal number of countries in the file (this is same<br />

as the number of lines)<br />

3 Total population – calculate the <strong>to</strong>tal poulation of the world.<br />

4 Total gdp – calculate the <strong>to</strong>tal gdp of the world.<br />

5 Country with longest name – identify the country with the longest name.<br />

6 Area of Africa – calculate the <strong>to</strong>tal area of all countries in Africa.<br />

7 Country 42 – identify the country on line 42 of the file (Afganistan is 1).<br />

8 Count the number of European countries with a per‐capita gdp more than that<br />

of ʺUnited Kingdomʺ (per capital gdp is gdp/population).<br />

Further questions need HashTables or other structures <strong>to</strong> be completed:<br />

9 Population by region – show the <strong>to</strong>tal population for each region. You will<br />

need <strong>to</strong> use a HashTable <strong>to</strong> do this.<br />

10 List the countries with a gdp greater than the <strong>to</strong>tal gdp of Africa.<br />

11 List the regions with a <strong>to</strong>tal population of more than 100 million.<br />

12 Find the region(s) in which all countries have a population of less than 1 million.<br />

13 A country has a population more than three times that of any of its neigbours<br />

(in the same region). Find it (or them).<br />

Agilent .NET Course: C# Basics 12


Name:<br />

Course: <strong>Intro</strong>duction <strong>to</strong> .NET<br />

Title: Arrays and Collections<br />

Instruc<strong>to</strong>r: <strong>Bill</strong> <strong>Buchanan</strong><br />

.NET


3 Arrays and Collections<br />

3.1 <strong>Intro</strong>duction<br />

This module covers the key elements of arrays, indexers and collections. It covers:<br />

• Arrays.<br />

• Reading from CSV files.<br />

• System.Collections.<br />

• ArrayLists.<br />

• HashTables.<br />

3.2 Arrays<br />

Simple variables, such as int, float, double and string only hold a single element.<br />

This is fine when we have only a few things <strong>to</strong> s<strong>to</strong>re, but it is difficult <strong>to</strong> process data<br />

elements in a sequential way. Thus, programming languages support arrays which<br />

allow more than one element <strong>to</strong> be s<strong>to</strong>red under a common name, which allows the<br />

elements <strong>to</strong> be indexed.<br />

In C# an array is created from an object of type System.Array, as illustrated in<br />

Figure 3.1. The main methods are:<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

BinarySearch()<br />

Clear()<br />

Clone()<br />

Copy()<br />

CopyTo()<br />

CreateInstance()<br />

GetLength()<br />

IndexOf()<br />

Initialize()<br />

LastIndexOf()<br />

Reverse()<br />

SetValue()<br />

Sort()<br />

Performs a binary on a one‐dimensional array<br />

Sets a range of elements <strong>to</strong> zero, False or NULL.<br />

Make a shallow copy of the array.<br />

Copies a range of values in an array.<br />

Copies one array <strong>to</strong> another.<br />

Create a multidimensional array.<br />

Return the number of elements in the array.<br />

Search for an object, and return the first index value of its place.<br />

Set all the elements in the array <strong>to</strong> their default value.<br />

Returns the last object in the array.<br />

Reverses the array.<br />

Sets a specific array element <strong>to</strong> a value.<br />

Performs a sort on the array.<br />

Agilent .NET Course: Arrays and Collections 2


and main properties are:<br />

IsFixedSize<br />

IsReadOnly<br />

Length<br />

Identifies if the array is a fixed size (get only)<br />

Identifies if the array is read‐only (get only)<br />

Identifies the length of the array (get only)<br />

Figure 3.1: System.Array<br />

C# contains the methods of the System.Array object. It also inherits the syntax of C<br />

for representing an array index, which uses square brackets <strong>to</strong> identify the element,<br />

such as:<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

myArray[15];<br />

for the element number 15. Note that C# starts its indexing at 0, thus myArray[15] is<br />

the 16th element of the array. To declare an array:<br />

type[] arrayName;<br />

For example <strong>to</strong> declare an array of doubles:<br />

double[] inputValues;<br />

This declares the type of the array. To then <strong>to</strong> initialize it the following is used:<br />

Agilent .NET Course: Arrays and Collections 3


inputValues = new double[5];<br />

which creates a new array with 5 elements (0 <strong>to</strong> 4).<br />

In Program 3.1 an array with 5 elements is created, after which the getValues()<br />

method is used <strong>to</strong> get these values from the user, after which the average() method<br />

is used <strong>to</strong> determine the average of the values. The v.Length property is used <strong>to</strong> determine<br />

the size of the array.<br />

Program 3.1: Program3_1_ArrayCalcAverage<br />

using System;<br />

namespace ConsoleApplication2<br />

{<br />

class ArrayExample01<br />

{<br />

static void getValues(double[] v)<br />

{<br />

int i;<br />

}<br />

for (i=0;i 1<br />

Value >> 2<br />

Value >> 3<br />

Value >> 4<br />

Value >> 5<br />

Average is 3<br />

Agilent .NET Course: Arrays and Collections 4


Note that the declaration of the array type does not actually create the array, and the<br />

line:<br />

double[] inputValues;<br />

double av<br />

av=inputValues[0];<br />

will cause a build error of:<br />

Use of unassigned local variable 'inputValues'<br />

As the array can not been created yet, and just contains a null value.<br />

3.2.1 Initializing arrays<br />

The arrays when they are initialized are <strong>set</strong> <strong>to</strong> a default value, such as zero for numeric<br />

data types, and null for strings. To initialise it with actual values, the required<br />

values are contained within curly brackets, such as:<br />

int i[] = {10,20,30,40,50}; // First element i[0], Last element i[4]<br />

double[] vals = {1.2,1.4,1.6,1.8,2.0};<br />

string[] menuItems = {"File", "Edit", "View", "Insert", "Tool", "Table"};<br />

This performs both the declaration of the array and its initialization. Program 3.2<br />

shows an example of the declaration of an array of strings.<br />

Program 3.2: Program3_2_ArrayInitializationStrings<br />

using System;<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

namespace ConsoleApplication2<br />

{<br />

class ArrayExample01<br />

{<br />

static void Main(string[] args)<br />

{<br />

int i;<br />

}<br />

}<br />

string[] ColourBands={"BLACK","BROWN","RED","ORANGE","YELLOW","GREEN"};<br />

for (i=0;i


4 is YELLOW<br />

5 is GREEN<br />

Program 3.3 uses an array of doubles which are initialized with certain values. It<br />

then uses a findSmallest() method <strong>to</strong> determine the lowest value. In this case the<br />

array (vals) is declared with seven elements (0 <strong>to</strong> 6).<br />

Program 3.3: Program3_3_ArrayInitializationNumeric<br />

using System;<br />

namespace ConsoleApplication2<br />

{<br />

class ArrayExample01<br />

{<br />

static double findSmallest(double[] v)<br />

{<br />

double smallest;<br />

smallest=v[0];<br />

for (int i=1; i


is replaced by (Program3_3_ArrayInitializationNumericForEach):<br />

foreach (string band in ColourBands)<br />

System.Console.WriteLine("{0}",band);<br />

For the example in Program 3.2 we can replace:<br />

for (int i=1; i


3.3 Reading from a CSV file<br />

One of the best ways <strong>to</strong> transfer information between applications is <strong>to</strong> save the data<br />

separated by commas. This format is known as CSV (Comma Separated Variables).<br />

An example format is:<br />

1,5,6,7,4,5,6,7,10,5,4,3,2,1<br />

For this we can read the file one line at a time, and then split the string using the<br />

Split() method. This can be contained with the foreach statement, <strong>to</strong> parse each part<br />

of the split text. The code which fills the array v is:<br />

do<br />

{<br />

text=reader.ReadLine();<br />

if (text==null) break;<br />

foreach (string substring in text.Split(','))<br />

{<br />

v[i]=Convert.ToDouble(substring);<br />

i++;<br />

}<br />

} while (text != null);<br />

Program 3.5 shows the complete code <strong>to</strong> read the data from the CSV file (using the<br />

fillData()), and display it <strong>to</strong> the screen (using the showData() method).<br />

Program 3.5: Program3_5_ArrayGenerateDataWithCSV<br />

using System;<br />

using System.IO;<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

namespace ConsoleApplication2<br />

{<br />

class ArrayExample02<br />

{<br />

const int ARRAYLIMIT=100;<br />

static void fillData(double[] v)<br />

{<br />

int i=0;<br />

FileInfo theSourceFile = new FileInfo("..\\..\\test.csv");<br />

StreamReader reader = theSourceFile.OpenText();<br />

string text;<br />

do<br />

{<br />

text=reader.ReadLine();<br />

if (text==null) break;<br />

foreach (string substring in text.Split(','))<br />

{<br />

v[i]=Convert.ToDouble(substring);<br />

i++;<br />

}<br />

} while (text != null);<br />

Agilent .NET Course: Arrays and Collections 8


}<br />

reader.Close();<br />

static void showData(double[] v)<br />

{<br />

int i;<br />

}<br />

for (i=0;i


ow. This is similar <strong>to</strong> a spreadsheet where the row is represented by a line, and the<br />

columns are delimited by commas. For example:<br />

Fred,20<br />

Bert,10<br />

Colin,15<br />

Berty,26<br />

Freddy,22<br />

We can then modify the reading method <strong>to</strong> parse the input line from<br />

the CSV file:<br />

do<br />

{<br />

text=reader.ReadLine();<br />

if (text==null) break;<br />

string[] str =text.Split(',');<br />

name[i]=str[0];<br />

age[i]=Convert.ToInt32(str[1]);<br />

i++;<br />

} while (text != null);<br />

The complete listing is given in Program 3.6.<br />

Program 3.6: Program3_6_ArrayGenerateDataWithCSVParse<br />

using System;<br />

using System.IO;<br />

namespace ConsoleApplication2<br />

{<br />

class ArrayExample02<br />

{<br />

const int ARRAYSIZE=100;<br />

static void fillData(string[] name, int[] age)<br />

{<br />

int i=0;<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

FileInfo theSourceFile = new FileInfo("..\\..\\test.csv");<br />

StreamReader reader = theSourceFile.OpenText();<br />

string text;<br />

do<br />

{<br />

text=reader.ReadLine();<br />

if (text==null) break;<br />

string[] str =text.Split(',');<br />

name[i]=str[0];<br />

age[i]=Convert.ToInt32(str[1]);<br />

i++;<br />

} while (text != null);<br />

reader.Close();<br />

Agilent .NET Course: Arrays and Collections 10


static void showData(string[] names, int[] age)<br />

{<br />

int i;<br />

}<br />

for (i=0;i


• System.Runtime.Serialization • System.Security<br />

• System.Runtime.Serialization.Formatters • System.Security.Cryp<strong>to</strong>graphy<br />

An important namespace is System.Collections which includes the following:<br />

System.Collections<br />

ArrayList<br />

BitArray<br />

CaseInsensitiveComparer<br />

CaseInsensitiveHashCodeProvider<br />

CollectionBase<br />

Comparer<br />

DictionaryBase<br />

DictionaryEntry<br />

Hashtable<br />

Queue<br />

ReadOnlyCollectionBase<br />

SortedList<br />

Stack<br />

3.5 ArrayLists<br />

As we have seen, the basic array declaration is rather limited in the methods that<br />

can be applied <strong>to</strong> it. The ArrayList improves this greatly by creating an array object<br />

that has many methods, such searching, deletion and insertion. Its main methods<br />

include:<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Add(object)<br />

Add an object <strong>to</strong> the end of an ArrayList.<br />

ArrayList(int)<br />

Initializes a new ArrayList with a given capacity.<br />

ArrayList()<br />

Initializes a new ArrayList with a default capacity.<br />

BinarySearch(object)<br />

Searches for a given object in an ArrayList.<br />

Clear() Removes all elements from the System.Collections.ArrayList.<br />

Clone()<br />

Creates a shallow copy of an ArrayList.<br />

Contains(object)<br />

Determines if an object is in an ArrayList.<br />

CopyTo(int,System.Array,int,int) Copies a range of elements from an ArrayList in<strong>to</strong> a<br />

one‐dimensional array, from a starting and ending<br />

index value.<br />

CopyTo(System.Array,int)<br />

Copies a range of elements from an ArrayList in<strong>to</strong> a<br />

one‐dimensional array, from a starting and ending<br />

index value.<br />

CopyTo(System.Array)<br />

Copies the entire ArrayList in<strong>to</strong> a one‐dimensioanl<br />

array.<br />

Agilent .NET Course: Arrays and Collections 12


GetEnumera<strong>to</strong>r(int,int)<br />

GetEnumera<strong>to</strong>r()<br />

GetRange(int,int)<br />

IndexOf(object,int,int)<br />

IndexOf(object,int)<br />

IndexOf(object)<br />

Insert(int,object)<br />

LastIndexOf(object,int,int)<br />

LastIndexOf(object,int)<br />

LastIndexOf(object)<br />

Remove(object)<br />

RemoveAt(int)<br />

RemoveRange(int,int)<br />

Repeat(object,int)<br />

Reverse(int,int)<br />

Reverse()<br />

Sort()<br />

ToArray(System.Type)<br />

ToArray()<br />

TrimToSize()<br />

Returns an enumera<strong>to</strong>r for a range within the Array‐<br />

List.<br />

Returns an enumera<strong>to</strong>r for the entire ArrayList.<br />

Gets an ArrayList for a range within an ArrayList<br />

Returns the index value of an object within a given<br />

index range, and contains a specific number of occurrences.<br />

Returns the index value of an object from a given<br />

starting point<br />

Returns the index value of an object<br />

Inserts an object at a given index value.<br />

Returns the last index value of an object<br />

Returns the last index value of an object<br />

Returns the last index value of an object<br />

Remove the first occurrence of an object.<br />

Remove object at a certain index value.<br />

Remove a range of objects.<br />

Repeat a number of objects.<br />

Reverse objects within a given range.<br />

Reverse all the objects.<br />

Sort the ArrayList.<br />

Copies elements from ArrayList <strong>to</strong> a new array of a<br />

given type.<br />

Copies elements from ArrayList <strong>to</strong> a new array.<br />

Set the capacity of the ArrayList.<br />

And the properties for ArrayList are:<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Capacity<br />

Count<br />

IsFixedSize<br />

IsReadOnly<br />

Specifies the number of elements the ArrayList can<br />

have (<strong>set</strong>/get).<br />

Returns the number of elements in the ArrayList (get).<br />

Returns whether the ArrayList has a fixed size (get).<br />

Returns whether the ArrayList is read‐only (get).<br />

Program 3.6 shows an enhancement <strong>to</strong> Program 3.5, but uses ArrayLists instead of<br />

an array. For this uses the Add() <strong>to</strong> add a new element <strong>to</strong> the ArrayList. The Count<br />

property thus correctly contains the number of elements added <strong>to</strong> the ArrayList.<br />

Program 3.7: Program3_7_ArrayListGenerateDataWithCSV<br />

namespace ConsoleApplication2<br />

{<br />

using System;<br />

using System.Collections; // required for ArrayList<br />

using System.IO; // required for File I/O<br />

Agilent .NET Course: Arrays and Collections 13


class ArrayExample02<br />

{<br />

static void fillData(ArrayList v)<br />

{<br />

int i=0;<br />

FileInfo theSourceFile = new FileInfo("..\\..\\test.csv");<br />

StreamReader reader = theSourceFile.OpenText();<br />

}<br />

string text;<br />

do<br />

{<br />

text=reader.ReadLine();<br />

if (text==null) break;<br />

foreach (string substring in text.Split(','))<br />

{<br />

v.Add(Convert.ToDouble(substring));<br />

i++;<br />

}<br />

} while (text != null);<br />

reader.Close();<br />

static void showData(ArrayList v)<br />

{<br />

int i;<br />

for (i=0;i


Program 3.8: Program3_8_ArrayListGenerateDataWithCSVFindAverage<br />

namespace ConsoleApplication2<br />

{<br />

using System;<br />

using System.Collections; // required for ArrayList<br />

using System.IO; // required for File I/O<br />

class ArrayExample02<br />

{<br />

static void fillData(ArrayList v)<br />

{<br />

int i=0;<br />

FileInfo theSourceFile = new FileInfo("..\\..\\test.csv");<br />

StreamReader reader = theSourceFile.OpenText();<br />

string text;<br />

do<br />

{<br />

text=reader.ReadLine();<br />

if (text==null) break;<br />

foreach (string substring in text.Split(','))<br />

{<br />

v.Add(Convert.ToDouble(substring));<br />

i++;<br />

}<br />

} while (text != null);<br />

}<br />

reader.Close();<br />

static void showData(ArrayList v)<br />

{<br />

int i;<br />

for (i=0;i


Sample Run 3.8<br />

Average is 4.71428571428571<br />

The ArrayList is contains many more methods than for arrays. An important<br />

method is sort(), which allows an ArrayList <strong>to</strong> be sorted. Program 3.9 shows an example<br />

of using this method, and the same run shows a run with the CSV file of:<br />

Smith,Fred<br />

Bell,Bert<br />

McDonald,Rory<br />

Mitchel,Brian<br />

Barr,Martin<br />

Kinlock,Graham<br />

Program 3.9: Program3_9_ArrayListGenerateDataWithCSVOrderedList<br />

namespace ConsoleApplication2<br />

{<br />

using System;<br />

using System.Collections; // required for ArrayList<br />

using System.IO; // required for File I/O<br />

class ArrayExample02<br />

{<br />

static void fillData(ArrayList v)<br />

{<br />

int i=0;<br />

FileInfo theSourceFile = new FileInfo("..\\..\\test.csv");<br />

StreamReader reader = theSourceFile.OpenText();<br />

string text;<br />

do<br />

{<br />

text=reader.ReadLine();<br />

if (text==null) break;<br />

v.Add(text);<br />

} while (text != null);<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

reader.Close();<br />

static void showData(ArrayList v)<br />

{<br />

int i;<br />

}<br />

for (i=0;i


}<br />

}<br />

}<br />

Vals.Sort();<br />

showData(Vals);<br />

System.Console.ReadLine();<br />

Sample Run 3.8<br />

0 Smith,Fred<br />

1 Bell,Bert<br />

2 McDonald,Rory<br />

3 Mitchel,Brian<br />

4 Barr,Martin<br />

5 Kinlock,Graha<br />

0 Barr,Martin<br />

1 Bell,Bert<br />

2 Kinlock,Graha<br />

3 McDonald,Rory<br />

4 Mitchel,Brian<br />

5 Smith,Fred<br />

3.6 HashTables<br />

HashTables represents a collection of key‐and‐value pairs that are organized based<br />

on the hash code of the key. They are particularly useful for fast retrieval of data<br />

from a list. They are basically dictionaries of data. The main methods are:<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Add(object,object)<br />

Clear()<br />

Clone()<br />

Contains(object)<br />

ContainsValue(object)<br />

CopyTo(System.Array,int)<br />

GetEnumera<strong>to</strong>r()<br />

GetHash(object)<br />

Hashtable(int)<br />

Hashtable()<br />

KeyEquals(object,object)<br />

Remove(object)<br />

And the main properties are:<br />

Count<br />

Adds elements with a specified key and value in<strong>to</strong> the<br />

Hashtable.<br />

Removes the elements in Hashtable.<br />

Creates a shallow copy of the Hashtable.<br />

Determines whether the Hashtable contains a certain key.<br />

Determines whether the Hashtable contains a certain value.<br />

Copies a parts of a Hashtable <strong>to</strong> a one‐dimensional Array<br />

instance.<br />

Returns an enumera<strong>to</strong>r value that can iterate through the<br />

Hashtable.<br />

Returns the hash code for the specified key.<br />

Create a empty Hashtable.<br />

Creates an empty Hashtable.<br />

Compares an object with the key.<br />

Removes the element with the specified key from the<br />

Hashtable.<br />

Gets the number of key‐pairs in the HashTable.<br />

Agilent .NET Course: Arrays and Collections 17


Key<br />

IsFixedSize<br />

IsReadOnly<br />

Value<br />

Gets the keys of the HashTable.<br />

Get whether the HashTable is fixed size.<br />

Determines whether the HashTable is read‐only.<br />

Get the values of the HashTable.<br />

The Hashtable uses a similar technique <strong>to</strong> add data <strong>to</strong> its list (with the Add()<br />

method). Once the table has been filled, the keys from the table can be generated<br />

from (using a Hashtable of v):<br />

ICollection keys = v.Keys;<br />

And the values in the list by:<br />

ICollection values = v.Values;<br />

Program 3.10 shows an example of a Hashtable. The same run uses the following<br />

data:<br />

00001,Smith<br />

00010,Bell<br />

00033,McDonald<br />

44444,Mitchel<br />

55555,Martin<br />

43251,Kinlock<br />

Program 3.10: Program3_10_HashTableSimple<br />

namespace ConsoleApplication2<br />

{<br />

using System;<br />

using System.Collections; // required for HashTable<br />

using System.IO; // required for File I/O<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

class ArrayExample02<br />

{<br />

static void fillData(Hashtable v)<br />

{<br />

FileInfo theSourceFile = new FileInfo("..\\..\\test.csv");<br />

}<br />

StreamReader reader = theSourceFile.OpenText();<br />

string text;<br />

do<br />

{<br />

text=reader.ReadLine();<br />

if (text==null) break;<br />

string[] str = text.Split(',');<br />

v.Add(str[0],str[1]);<br />

} while (text != null);<br />

reader.Close();<br />

static void showData(Hashtable v)<br />

Agilent .NET Course: Arrays and Collections 18


{<br />

int i;<br />

ICollection keys = v.Keys;<br />

ICollection values = v.Values;<br />

System.Console.WriteLine("Keys are: ");<br />

foreach (string key in keys)<br />

Console.WriteLine("{0}",key);<br />

System.Console.WriteLine("Values are: ");<br />

foreach (string val in values)<br />

Console.WriteLine("{0}",val);<br />

}<br />

static void Main(string[] args)<br />

{<br />

Hashtable Vals = new Hashtable();<br />

}<br />

}<br />

}<br />

fillData(Vals);<br />

showData(Vals);<br />

System.Console.ReadLine();<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Sample Run 3.10<br />

Keys are:<br />

00001<br />

00010<br />

00033<br />

44444<br />

55555<br />

43251<br />

Values are:<br />

Smith<br />

Bell<br />

McDonald<br />

Mitchel<br />

Martin<br />

Kinlock<br />

It is possible <strong>to</strong> browse through the dictionary by creating an enumera<strong>to</strong>r (using the<br />

GetEnumera<strong>to</strong>r() method). This creates a list of references <strong>to</strong> the elements in the<br />

hashtable. This is achieved with the following (for a hashtable of v):<br />

System.Collections.IDictionaryEnumera<strong>to</strong>r enumera<strong>to</strong>r = v.GetEnumera<strong>to</strong>r();<br />

while (enumera<strong>to</strong>r.MoveNext())<br />

{<br />

Console.WriteLine("{0} {1}",enumera<strong>to</strong>r.Key, enumera<strong>to</strong>r.Value);<br />

}<br />

A complete program is shown in Program 3.11.<br />

Agilent .NET Course: Arrays and Collections 19


Program 3.11: Program3_11_HashTableSimpleEnumera<strong>to</strong>r<br />

namespace ConsoleApplication2<br />

{<br />

using System;<br />

using System.Collections; // required for HashTable<br />

using System.IO; // required for File I/O<br />

class ArrayExample02<br />

{<br />

static void fillData(Hashtable v)<br />

{<br />

FileInfo theSourceFile = new FileInfo("..\\..\\test.csv");<br />

StreamReader reader = theSourceFile.OpenText();<br />

string text;<br />

do<br />

{<br />

text=reader.ReadLine();<br />

if (text==null) break;<br />

string[] str = text.Split(',');<br />

v.Add(str[0],str[1]);<br />

} while (text != null);<br />

}<br />

reader.Close();<br />

static void showData(Hashtable v)<br />

{<br />

System.Collections.IDictionaryEnumera<strong>to</strong>r enumera<strong>to</strong>r = v.GetEnumera<strong>to</strong>r();<br />

}<br />

while (enumera<strong>to</strong>r.MoveNext())<br />

{<br />

Console.WriteLine("{0} {1}",enumera<strong>to</strong>r.Key, enumera<strong>to</strong>r.Value);<br />

}<br />

static void Main(string[] args)<br />

{<br />

Hashtable Vals = new Hashtable();<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

}<br />

fillData(Vals);<br />

showData(Vals);<br />

System.Console.ReadLine();<br />

}<br />

Sample Run 3.11<br />

00001 Smith<br />

00010 Bell<br />

00033 McDonald<br />

44444 Mitchel<br />

55555 Martin<br />

43251 Kinlock<br />

Agilent .NET Course: Arrays and Collections 20


Name:<br />

Course: <strong>Intro</strong>duction <strong>to</strong> .NET<br />

Title: Types and Debugging<br />

Instruc<strong>to</strong>r: <strong>Bill</strong> <strong>Buchanan</strong><br />

.NET


4 Types and Debugging<br />

4.1 <strong>Intro</strong>duction<br />

This module covers the key elements of arrays, indexers and collections. It covers:<br />

• Reference types.<br />

• Common reference type.<br />

• Namespaces and object hierarchy.<br />

• Debugging.<br />

4.2 Reference Types<br />

Parameters are passed in<strong>to</strong> function member, such as methods or properties,<br />

either using a value or a reference. If a value is passed, only the contents of<br />

the value are used, thus it cannot be modified. It a reference it passed, the<br />

function member can modify the value. A value passed by reference uses the<br />

ref keyword, such as:<br />

swap(ref int a, ref int b)<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

4.2.1 Passing Value-Type Parameters<br />

This is the simplest case, where a copy of the value of the data is passed. Thus an<br />

changes <strong>to</strong> the parameters will be lost. For example in Figure 4.1 the value of val1 is<br />

passed in x. This is then modified in the method <strong>to</strong> give the square of the value.<br />

When it returns from the method, it can be seen from the sample run that the value<br />

of val1 has not change (as it remains at 10).<br />

Program 4.1: Program4_1_PassingByValue<br />

using System;<br />

namespace ConsoleApplication2<br />

{<br />

class Class1<br />

{<br />

static double findSquare(double x)<br />

{<br />

Agilent .NET Course: Type and Debugging 2


}<br />

x *= x;<br />

System.Console.WriteLine("Value in the method is {0}",x);<br />

return(x);<br />

static void Main(string[] args)<br />

{<br />

double val1,val2;<br />

val1=10;<br />

}<br />

}<br />

}<br />

val2=findSquare(val1);<br />

System.Console.WriteLine("Value now is {0}",val1);<br />

System.Console.ReadLine();<br />

Sample Run Error! Reference source not found.<br />

Value in the method is 100<br />

Value now is 10<br />

4.2.2 Passing by reference<br />

It is possible <strong>to</strong> pass a reference of a parameter, so that the parameter is changed by<br />

the method. For this the ref keyword is inserted before the variable that is passed. It<br />

can be see from the test run of Program 4.2 that the actual value of the parameter<br />

can now be changed by the method.<br />

Program 4.2: Program4_2_PassingByReference<br />

using System;<br />

namespace ConsoleApplication2<br />

{<br />

class Class1<br />

{<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

static double findSquare(ref double x)<br />

{<br />

x *= x;<br />

System.Console.WriteLine("Value in the method is {0}",x);<br />

return(x);<br />

}<br />

static void Main(string[] args)<br />

{<br />

double val1,val2;<br />

}<br />

val1=10;<br />

val2=findSquare(ref val1);<br />

System.Console.WriteLine("Value now is {0}",val1);<br />

System.Console.ReadLine();<br />

Agilent .NET Course: Type and Debugging 3


}<br />

}<br />

Sample Run Error! Reference source not found.<br />

Value in the method is 100<br />

Value now is 100<br />

Array values are always passed by reference, thus there contents are changed if the<br />

method changes them. For example in Program 4.3. the clampArray() method scans<br />

an array, and if the value is greater than a certain value, the value is clamped. As<br />

can be seen from the sample run some of the values in the array have been changed<br />

by the method.<br />

Program 4.3: Program4_3_PassingArrays<br />

namespace ConsoleApplication2<br />

{<br />

class Class1<br />

{<br />

static void clampArray(double[] x, int c)<br />

{<br />

for (int i=0;iclamp) x[i]=c;<br />

}<br />

static void Main(string[] args)<br />

{<br />

double[] vals={0,1,2,3,4,5,6};<br />

int clamp=3,i;<br />

clampArray(vals,clamp);<br />

duction <strong>to</strong> .NET<br />

}<br />

}<br />

}<br />

for (i=0;i


4.3 Common reference types<br />

The common type system allows either value or reference types. A value contains<br />

the normal data type declarations. Reference types relate <strong>to</strong> value’s actual memory<br />

address, which is allocated on the heap. An example of reference types is an array<br />

which is allocated as a pointer <strong>to</strong> the array elements. Referenced values can be used<br />

<strong>to</strong> provide a reference for other variables, where a change in one while be reflected<br />

in the other.<br />

Program 4.4: Program4_3_PassingArrays<br />

using System;<br />

namespace ConsoleApplication2<br />

{<br />

class Test1<br />

{<br />

public int Value = 0;<br />

}<br />

class Class1<br />

{<br />

static void Main()<br />

{<br />

int val1 = 0;<br />

int val2 = val1;<br />

val1 = 99;<br />

Test1 ref1 = new Test1();<br />

Test1 ref2 = ref1;<br />

ref2.Value = 123;<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Console.WriteLine("Values: {0}, {1}", val1, val2);<br />

Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);<br />

Console.ReadLine();<br />

}<br />

}<br />

}<br />

Sample Run Error! Reference source not found.<br />

Values: 99, 0<br />

Refs: 123, 123<br />

For example in the following code, arr2 is a reference <strong>to</strong> arr1. Thus if we change any<br />

of the elements in arr1, the same change will be reflected in arr2.<br />

double [] arr1={0,1,2,3};<br />

double [] arr2=arr1;<br />

arr1[0]=5;<br />

Agilent .NET Course: Type and Debugging 5


Thus the result of this is that arr2[0] will be changed <strong>to</strong> 5.<br />

4.4 Namespaces and Object Hierarchy<br />

The .NET Framework supports a class library structure which has a number of<br />

namespaces. These include:<br />

• Microsoft.CSharp. These are the classes that relate <strong>to</strong> C#<br />

• Microsoft.VisualBasic. These are the classes that relate <strong>to</strong> Visual Basic.<br />

The System namespace contains all the fundamental classes that are commonly used<br />

in programs, and include:<br />

• Array.<br />

• Buffer.<br />

• Console.<br />

• Convert.<br />

• Enum.<br />

• Math.<br />

• String.<br />

The complete object hierarchy is given in Appendix A. Some examples are:<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.Object<br />

Microsoft.CSharp.Compiler<br />

Microsoft.CSharp.CompilerError<br />

Microsoft.Win32.Registry<br />

Microsoft.Win32.SystemEvents<br />

System.Activa<strong>to</strong>r<br />

System.AppDomainSetup<br />

System.Array<br />

System.Attribute<br />

System.BitConverter<br />

System.Buffer<br />

System.IO.BinaryReader<br />

System.IO.BinaryWriter<br />

System.IO.Direc<strong>to</strong>ry<br />

System.IO.File<br />

System.IO.Path<br />

System.Collections.ArrayList<br />

System.Collections.BitArray<br />

System.Collections.CaseInsensitiveComparer<br />

System.Collections.CaseInsensitiveHashCodeProvider<br />

Agilent .NET Course: Type and Debugging 6


System.Collections.CollectionBase<br />

System.Collections.Comparer<br />

System.Collections.DictionaryBase<br />

System.Collections.Hashtable<br />

System.Collections.Queue<br />

System.Net.AuthenticationManager<br />

System.Net.Authorization<br />

System.Net.Cookie<br />

System.Net.CookieCollection<br />

System.Net.CookieContainer<br />

System.Net.CredentialCache<br />

System.Net.Dns<br />

System.Net.EndPoint<br />

System.Net.EndpointPermission<br />

System.Net.GlobalProxySelection<br />

System.String<br />

4.5 Debugging<br />

There are normally two ways <strong>to</strong> debug a program:<br />

• Human output. This is where extra debug information is outputted when the<br />

program is run.<br />

• Using the debugger. This is where the program can be stepped‐though, and the<br />

variables in the program examined.<br />

The main elements of the debugger are:<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

• Watch window. This is opened when the debugger is running and is selected<br />

from Debug ‐> Windows‐>Watch, and then clicking on Watch1, Watch2, Watch3,<br />

or Watch4.<br />

• QuickWatch dialog box. This is used when the debugger is in a break state, and<br />

enables variables <strong>to</strong> be viewed.<br />

• Memory Window. This is viewing when debugging, and is selected from Debug‐><br />

Windows, and then clicking on Memory, and choose Memory 1, Memory<br />

2, Memory 3, or Memory 4.<br />

The F11 key is used <strong>to</strong> step through the program, where the debugger goes in<strong>to</strong> each<br />

method, whereas the F10 key steps over methods. A break point is added with the<br />

Ctrl‐B keystroke. Examples of a debugging process is shown next:<br />

Agilent .NET Course: Type and Debugging 7


4.6 Converting data types<br />

The System.Convert class has many methods including:<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

• ToBoolean()<br />

• ToByte()<br />

• ToChar()<br />

• ToDateTime()<br />

• ToDouble()<br />

• ToInt16()<br />

• ToInt32()<br />

4.7 Appendix A<br />

System.Object<br />

Microsoft.CSharp.Compiler<br />

Microsoft.CSharp.CompilerError<br />

Microsoft.Win32.Registry<br />

Microsoft.Win32.SystemEvents<br />

System.Activa<strong>to</strong>r<br />

System.AppDomainSetup<br />

System.Array<br />

System.Attribute<br />

System.BitConverter<br />

Agilent .NET Course: Type and Debugging 8


duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.Buffer<br />

System.CharEnumera<strong>to</strong>r<br />

System.CodeDom.CodeAttributeArgument<br />

System.CodeDom.CodeAttributeDeclaration<br />

System.CodeDom.CodeCatchClause<br />

System.CodeDom.CodeLinePragma<br />

System.CodeDom.CodeNamespaceImportCollection<br />

System.CodeDom.CodeObject<br />

System.CodeDom.Compiler.CodeGenera<strong>to</strong>r<br />

System.CodeDom.Compiler.CodeGenera<strong>to</strong>rOptions<br />

System.CodeDom.Compiler.CodeParser<br />

System.CodeDom.Compiler.CompilerError<br />

System.CodeDom.Compiler.CompilerParameters<br />

System.CodeDom.Compiler.CompilerResults<br />

System.CodeDom.Compiler.Execu<strong>to</strong>r<br />

System.CodeDom.Compiler.TempFileCollection<br />

System.Collections.ArrayList<br />

System.Collections.BitArray<br />

System.Collections.CaseInsensitiveComparer<br />

System.Collections.CaseInsensitiveHashCodeProvider<br />

System.Collections.CollectionBase<br />

System.Collections.Comparer<br />

System.Collections.DictionaryBase<br />

System.Collections.Hashtable<br />

System.Collections.Queue<br />

System.Collections.ReadOnlyCollectionBase<br />

System.Collections.SortedList<br />

System.Collections.Specialized.CollectionsUtil<br />

System.Collections.Specialized.HybridDictionary<br />

System.Collections.Specialized.ListDictionary<br />

System.Collections.Specialized.NameObjectCollectionBase<br />

System.Collections.Specialized.NameObjectCollectionBase.KeysCollection<br />

System.Collections.Specialized.StringCollection<br />

System.Collections.Specialized.StringDictionary<br />

System.Collections.Specialized.StringEnumera<strong>to</strong>r<br />

System.Collections.Stack<br />

System.ComponentModel.AttributeCollection<br />

System.ComponentModel.ComponentEdi<strong>to</strong>r<br />

System.ComponentModel.Container<br />

System.ComponentModel.Design.CommandID<br />

System.ComponentModel.Design.ComponentDesigner<br />

System.ComponentModel.Design.ComponentDesigner.ShadowPropertyCollection<br />

System.ComponentModel.Design.DesignerCollection<br />

System.ComponentModel.Design.DesignerTransaction<br />

System.ComponentModel.Design.DesigntimeLicenseContextSerializer<br />

System.ComponentModel.Design.LocalizationExtenderProvider<br />

System.ComponentModel.Design.MenuCommand<br />

System.ComponentModel.Design.Serialization.CodeDomSerializer<br />

System.ComponentModel.Design.Serialization.ContextStack<br />

System.ComponentModel.Design.Serialization.DesignerLoader<br />

System.ComponentModel.Design.Serialization.InstanceDescrip<strong>to</strong>r<br />

System.ComponentModel.Design.ServiceContainer<br />

System.ComponentModel.Design.StandardCommands<br />

System.ComponentModel.Design.StandardToolWindows<br />

System.ComponentModel.EventDescrip<strong>to</strong>rCollection<br />

Agilent .NET Course: Type and Debugging 9


duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.ComponentModel.EventHandlerList<br />

System.ComponentModel.License<br />

System.ComponentModel.LicenseContext<br />

System.ComponentModel.LicenseManager<br />

System.ComponentModel.LicenseProvider<br />

System.ComponentModel.MarshalByValueComponent<br />

System.ComponentModel.MemberDescrip<strong>to</strong>r<br />

System.ComponentModel.PropertyDescrip<strong>to</strong>rCollection<br />

System.ComponentModel.TypeConverter<br />

System.ComponentModel.TypeConverter.StandardValuesCollection<br />

System.ComponentModel.TypeDescrip<strong>to</strong>r<br />

System.Configuration.AppSettingsReader<br />

System.Configuration.ConfigurationSettings<br />

System.Configuration.DictionarySectionHandler<br />

System.Configuration.IgnoreSectionHandler<br />

System.Configuration.Install.InstallContext<br />

System.Configuration.NameValueSectionHandler<br />

System.Configuration.SingleTagSectionHandler<br />

System.Console<br />

System.Convert<br />

System.Data.Common.DbDataRecord<br />

System.Data.Common.DbEnumera<strong>to</strong>r<br />

System.Data.Constraint<br />

System.Data.DataRelation<br />

System.Data.DataRow<br />

System.Data.DataRowView<br />

System.Data.DataViewSetting<br />

System.Data.DataViewSettingCollection<br />

System.Data.InternalDataCollectionBase<br />

System.Data.Odbc.OdbcError<br />

System.Data.Odbc.OdbcErrorCollection<br />

System.Data.OleDb.OleDbError<br />

System.Data.OleDb.OleDbErrorCollection<br />

System.Data.OleDb.OleDbSchemaGuid<br />

System.Data.SqlClient.SqlError<br />

System.Data.SqlClient.SqlErrorCollection<br />

System.Data.SqlServerCe.SqlCeError<br />

System.Data.SqlServerCe.SqlCeErrorCollection<br />

System.Data.TypedDataSetGenera<strong>to</strong>r<br />

System.DBNull<br />

System.Delegate<br />

System.Diagnostics.CounterCreationData<br />

System.Diagnostics.CounterSampleCalcula<strong>to</strong>r<br />

System.Diagnostics.Debug<br />

System.Diagnostics.Debugger<br />

System.Diagnostics.EventLogEntryCollection<br />

System.Diagnostics.EventLogPermissionEntry<br />

System.Diagnostics.FileVersionInfo<br />

System.Diagnostics.InstanceData<br />

System.Diagnostics.PerformanceCounterCategory<br />

System.Diagnostics.PerformanceCounterPermissionEntry<br />

System.Diagnostics.ProcessStartInfo<br />

System.Diagnostics.StackFrame<br />

System.Diagnostics.StackTrace<br />

System.Diagnostics.Switch<br />

Agilent .NET Course: Type and Debugging 10


duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.Diagnostics.SymbolS<strong>to</strong>re.SymDocumentType<br />

System.Diagnostics.SymbolS<strong>to</strong>re.SymLanguageType<br />

System.Diagnostics.SymbolS<strong>to</strong>re.SymLanguageVendor<br />

System.Diagnostics.Trace<br />

System.Diagnostics.TraceListenerCollection<br />

System.Direc<strong>to</strong>ryServices.Direc<strong>to</strong>ryEntries<br />

System.Direc<strong>to</strong>ryServices.Direc<strong>to</strong>ryServicesPermissionEntry<br />

System.Direc<strong>to</strong>ryServices.PropertyCollection<br />

System.Direc<strong>to</strong>ryServices.SchemaNameCollection<br />

System.Direc<strong>to</strong>ryServices.SearchResult<br />

System.Direc<strong>to</strong>ryServices.SortOption<br />

System.Drawing.Brushes<br />

System.Drawing.ColorTransla<strong>to</strong>r<br />

System.Drawing.Design.PropertyValueUIItem<br />

System.Drawing.Design.ToolboxItem<br />

System.Drawing.Design.UITypeEdi<strong>to</strong>r<br />

System.Drawing.Drawing2D.Blend<br />

System.Drawing.Drawing2D.ColorBlend<br />

System.Drawing.Drawing2D.PathData<br />

System.Drawing.Drawing2D.RegionData<br />

System.Drawing.ImageAnima<strong>to</strong>r<br />

System.Drawing.Imaging.BitmapData<br />

System.Drawing.Imaging.ColorMap<br />

System.Drawing.Imaging.ColorMatrix<br />

System.Drawing.Imaging.ColorPalette<br />

System.Drawing.Imaging.Encoder<br />

System.Drawing.Imaging.EncoderParameter<br />

System.Drawing.Imaging.EncoderParameters<br />

System.Drawing.Imaging.FrameDimension<br />

System.Drawing.Imaging.ImageAttributes<br />

System.Drawing.Imaging.ImageCodecInfo<br />

System.Drawing.Imaging.ImageFormat<br />

System.Drawing.Imaging.MetafileHeader<br />

System.Drawing.Imaging.MetaHeader<br />

System.Drawing.Imaging.PropertyItem<br />

System.Drawing.Imaging.WmfPlaceableFileHeader<br />

System.Drawing.Pens<br />

System.Drawing.Printing.Margins<br />

System.Drawing.Printing.PageSettings<br />

System.Drawing.Printing.PaperSize<br />

System.Drawing.Printing.PaperSource<br />

System.Drawing.Printing.PreviewPageInfo<br />

System.Drawing.Printing.PrintController<br />

System.Drawing.Printing.PrinterResolution<br />

System.Drawing.Printing.PrinterSettings<br />

System.Drawing.Printing.PrinterSettings.PaperSizeCollection<br />

System.Drawing.Printing.PrinterSettings.PaperSourceCollection<br />

System.Drawing.Printing.PrinterSettings.PrinterResolutionCollection<br />

System.Drawing.Printing.PrinterUnitConvert<br />

System.Drawing.SystemBrushes<br />

System.Drawing.SystemColors<br />

System.Drawing.SystemIcons<br />

System.Drawing.SystemPens<br />

System.Drawing.Text.FontCollection<br />

System.EnterpriseServices.Activity<br />

Agilent .NET Course: Type and Debugging 11


duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.EnterpriseServices.BYOT<br />

System.EnterpriseServices.CompensatingResourceManager.Clerk<br />

System.EnterpriseServices.CompensatingResourceManager.ClerkInfo<br />

System.EnterpriseServices.CompensatingResourceManager.ClerkMoni<strong>to</strong>r<br />

System.EnterpriseServices.CompensatingResourceManager.LogRecord<br />

System.EnterpriseServices.ContextUtil<br />

System.EnterpriseServices.Internal.AppDomainHelper<br />

System.EnterpriseServices.Internal.ClrObjectFac<strong>to</strong>ry<br />

System.EnterpriseServices.Internal.ComManagedImportUtil<br />

System.EnterpriseServices.Internal.Publish<br />

System.EnterpriseServices.Internal.SoapClientImport<br />

System.EnterpriseServices.Internal.SoapServerTlb<br />

System.EnterpriseServices.Internal.SoapServerVRoot<br />

System.EnterpriseServices.Internal.SoapUtility<br />

System.EnterpriseServices.RegistrationConfig<br />

System.EnterpriseServices.RegistrationErrorInfo<br />

System.EnterpriseServices.ResourcePool<br />

System.EnterpriseServices.SecurityCallContext<br />

System.EnterpriseServices.SecurityCallers<br />

System.EnterpriseServices.SecurityIdentity<br />

System.EnterpriseServices.ServiceConfig<br />

System.EnterpriseServices.ServiceDomain<br />

System.EnterpriseServices.SharedProperty<br />

System.EnterpriseServices.SharedPropertyGroup<br />

System.EnterpriseServices.SharedPropertyGroupManager<br />

System.Environment<br />

System.EventArgs<br />

System.Exception<br />

System.GC<br />

System.Globalization.Calendar<br />

System.Globalization.CompareInfo<br />

System.Globalization.CultureInfo<br />

System.Globalization.DateTimeFormatInfo<br />

System.Globalization.DaylightTime<br />

System.Globalization.NumberFormatInfo<br />

System.Globalization.RegionInfo<br />

System.Globalization.SortKey<br />

System.Globalization.StringInfo<br />

System.Globalization.TextElementEnumera<strong>to</strong>r<br />

System.Globalization.TextInfo<br />

System.IO.BinaryReader<br />

System.IO.BinaryWriter<br />

System.IO.Direc<strong>to</strong>ry<br />

System.IO.File<br />

System.IO.Path<br />

System.LocalDataS<strong>to</strong>reSlot<br />

System.Management.Instrumentation.BaseEvent<br />

System.Management.Instrumentation.Instance<br />

System.Management.Instrumentation.Instrumentation<br />

System.Management.ManagementDateTimeConverter<br />

System.Management.ManagementObjectCollection<br />

System.Management.ManagementObjectCollection.ManagementObjectEnumera<strong>to</strong>r<br />

System.Management.ManagementOperationObserver<br />

System.Management.ManagementOptions<br />

System.Management.ManagementPath<br />

Agilent .NET Course: Type and Debugging 12


duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.Management.ManagementQuery<br />

System.Management.ManagementScope<br />

System.Management.MethodData<br />

System.Management.MethodDataCollection<br />

System.Management.MethodDataCollection.MethodDataEnumera<strong>to</strong>r<br />

System.Management.PropertyData<br />

System.Management.PropertyDataCollection<br />

System.Management.PropertyDataCollection.PropertyDataEnumera<strong>to</strong>r<br />

System.Management.QualifierData<br />

System.Management.QualifierDataCollection<br />

System.Management.QualifierDataCollection.QualifierDataEnumera<strong>to</strong>r<br />

System.MarshalByRefObject<br />

System.Math<br />

System.Messaging.AccessControlEntry<br />

System.Messaging.ActiveXMessageFormatter<br />

System.Messaging.BinaryMessageFormatter<br />

System.Messaging.DefaultPropertiesToSend<br />

System.Messaging.MessagePropertyFilter<br />

System.Messaging.MessageQueueCriteria<br />

System.Messaging.MessageQueuePermissionEntry<br />

System.Messaging.MessageQueueTransaction<br />

System.Messaging.Trustee<br />

System.Messaging.XmlMessageFormatter<br />

System.Net.AuthenticationManager<br />

System.Net.Authorization<br />

System.Net.Cookie<br />

System.Net.CookieCollection<br />

System.Net.CookieContainer<br />

System.Net.CredentialCache<br />

System.Net.Dns<br />

System.Net.EndPoint<br />

System.Net.EndpointPermission<br />

System.Net.GlobalProxySelection<br />

System.Net.HttpVersion<br />

System.Net.IPAddress<br />

System.Net.IPHostEntry<br />

System.Net.NetworkCredential<br />

System.Net.ServicePoint<br />

System.Net.ServicePointManager<br />

System.Net.SocketAddress<br />

System.Net.Sockets.IPv6MulticastOption<br />

System.Net.Sockets.IrDAClient<br />

System.Net.Sockets.IrDADeviceInfo<br />

System.Net.Sockets.IrDAListener<br />

System.Net.Sockets.LingerOption<br />

System.Net.Sockets.MulticastOption<br />

System.Net.Sockets.Socket<br />

System.Net.Sockets.TcpClient<br />

System.Net.Sockets.TcpListener<br />

System.Net.Sockets.UdpClient<br />

System.Net.WebProxy<br />

System.OperatingSystem<br />

System.Random<br />

System.Reflection.Assembly<br />

System.Reflection.AssemblyName<br />

Agilent .NET Course: Type and Debugging 13


duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.Reflection.Binder<br />

System.Reflection.Emit.Cus<strong>to</strong>mAttributeBuilder<br />

System.Reflection.Emit.EventBuilder<br />

System.Reflection.Emit.ILGenera<strong>to</strong>r<br />

System.Reflection.Emit.LocalBuilder<br />

System.Reflection.Emit.MethodRental<br />

System.Reflection.Emit.OpCodes<br />

System.Reflection.Emit.ParameterBuilder<br />

System.Reflection.Emit.SignatureHelper<br />

System.Reflection.Emit.UnmanagedMarshal<br />

System.Reflection.ManifestResourceInfo<br />

System.Reflection.MemberInfo<br />

System.Reflection.Missing<br />

System.Reflection.Module<br />

System.Reflection.ParameterInfo<br />

System.Reflection.Pointer<br />

System.Reflection.StrongNameKeyPair<br />

System.Resources.ResourceManager<br />

System.Resources.ResourceReader<br />

System.Resources.ResourceSet<br />

System.Resources.ResourceWriter<br />

System.Resources.ResXFileRef<br />

System.Resources.ResXResourceReader<br />

System.Resources.ResXResourceWriter<br />

System.Runtime.CompilerServices.CallConvCdecl<br />

System.Runtime.CompilerServices.CallConvFastcall<br />

System.Runtime.CompilerServices.CallConvStdcall<br />

System.Runtime.CompilerServices.CallConvThiscall<br />

System.Runtime.CompilerServices.IsVolatile<br />

System.Runtime.CompilerServices.RuntimeHelpers<br />

System.Runtime.InteropServices.CurrencyWrapper<br />

System.Runtime.InteropServices.Cus<strong>to</strong>mMarshalers.EnumerableToDispatchMarshaler<br />

System.Runtime.InteropServices.Cus<strong>to</strong>mMarshalers.Enumera<strong>to</strong>rToEnumVariantMarshaler<br />

System.Runtime.InteropServices.Cus<strong>to</strong>mMarshalers.ExpandoToDispatchExMarshaler<br />

System.Runtime.InteropServices.Cus<strong>to</strong>mMarshalers.TypeToTypeInfoMarshaler<br />

System.Runtime.InteropServices.DispatchWrapper<br />

System.Runtime.InteropServices.ErrorWrapper<br />

System.Runtime.InteropServices.ExtensibleClassFac<strong>to</strong>ry<br />

System.Runtime.InteropServices.Marshal<br />

System.Runtime.InteropServices.RegistrationServices<br />

System.Runtime.InteropServices.RuntimeEnvironment<br />

System.Runtime.InteropServices.TypeLibConverter<br />

System.Runtime.InteropServices.UnknownWrapper<br />

System.Runtime.Remoting.Channels.BaseChannelObjectWithProperties<br />

System.Runtime.Remoting.Channels.BinaryClientFormatterSink<br />

System.Runtime.Remoting.Channels.BinaryClientFormatterSinkProvider<br />

System.Runtime.Remoting.Channels.BinaryServerFormatterSink<br />

System.Runtime.Remoting.Channels.BinaryServerFormatterSinkProvider<br />

System.Runtime.Remoting.Channels.ChannelDataS<strong>to</strong>re<br />

System.Runtime.Remoting.Channels.ChannelServices<br />

System.Runtime.Remoting.Channels.ClientChannelSinkStack<br />

System.Runtime.Remoting.Channels.CommonTransportKeys<br />

System.Runtime.Remoting.Channels.Http.HttpRemotingHandler<br />

System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFac<strong>to</strong>ry<br />

System.Runtime.Remoting.Channels.ServerChannelSinkStack<br />

Agilent .NET Course: Type and Debugging 14


duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.Runtime.Remoting.Channels.SinkProviderData<br />

System.Runtime.Remoting.Channels.SoapClientFormatterSink<br />

System.Runtime.Remoting.Channels.SoapClientFormatterSinkProvider<br />

System.Runtime.Remoting.Channels.SoapServerFormatterSink<br />

System.Runtime.Remoting.Channels.SoapServerFormatterSinkProvider<br />

System.Runtime.Remoting.Channels.Tcp.TcpChannel<br />

System.Runtime.Remoting.Channels.Tcp.TcpClientChannel<br />

System.Runtime.Remoting.Channels.Tcp.TcpServerChannel<br />

System.Runtime.Remoting.Channels.TransportHeaders<br />

System.Runtime.Remoting.Lifetime.LifetimeServices<br />

System.Runtime.Remoting.Messaging.AsyncResult<br />

System.Runtime.Remoting.Messaging.CallContext<br />

System.Runtime.Remoting.Messaging.Header<br />

System.Runtime.Remoting.Messaging.LogicalCallContext<br />

System.Runtime.Remoting.Messaging.RemotingSurrogateSelec<strong>to</strong>r<br />

System.Runtime.Remoting.Messaging.ReturnMessage<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapAnyUri<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapBase64Binary<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapDate<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapDateTime<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapDay<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapDuration<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapEntities<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapEntity<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapId<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapIdref<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapIdrefs<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapInteger<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapLanguage<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapMonth<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapMonthDay<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapName<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapNcName<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapNegativeInteger<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapNm<strong>to</strong>ken<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapNm<strong>to</strong>kens<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapNonNegativeInteger<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapNonPositiveInteger<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapNormalizedString<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapNotation<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapPositiveInteger<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapQName<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapTime<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapToken<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapYear<br />

System.Runtime.Remoting.Metadata.W3cXsd2001.SoapYearMonth<br />

System.Runtime.Remoting.MetadataServices.MetaData<br />

System.Runtime.Remoting.MetadataServices.SdlChannelSink<br />

System.Runtime.Remoting.MetadataServices.SdlChannelSinkProvider<br />

System.Runtime.Remoting.MetadataServices.ServiceType<br />

System.Runtime.Remoting.ObjRef<br />

System.Runtime.Remoting.Proxies.RealProxy<br />

System.Runtime.Remoting.RemotingConfiguration<br />

System.Runtime.Remoting.RemotingServices<br />

Agilent .NET Course: Type and Debugging 15


duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.Runtime.Remoting.Services.EnterpriseServicesHelper<br />

System.Runtime.Remoting.Services.TrackingServices<br />

System.Runtime.Remoting.SoapServices<br />

System.Runtime.Remoting.TypeEntry<br />

System.Runtime.Serialization.Formatter<br />

System.Runtime.Serialization.FormatterConverter<br />

System.Runtime.Serialization.Formatters.Binary.BinaryFormatter<br />

System.Runtime.Serialization.Formatters.ServerFault<br />

System.Runtime.Serialization.Formatters.Soap.SoapFormatter<br />

System.Runtime.Serialization.Formatters.SoapFault<br />

System.Runtime.Serialization.Formatters.SoapMessage<br />

System.Runtime.Serialization.FormatterServices<br />

System.Runtime.Serialization.ObjectIDGenera<strong>to</strong>r<br />

System.Runtime.Serialization.ObjectManager<br />

System.Runtime.Serialization.SerializationBinder<br />

System.Runtime.Serialization.SerializationInfo<br />

System.Runtime.Serialization.SerializationInfoEnumera<strong>to</strong>r<br />

System.Runtime.Serialization.SurrogateSelec<strong>to</strong>r<br />

System.Security.CodeAccessPermission<br />

System.Security.Cryp<strong>to</strong>graphy.AsymmetricAlgorithm<br />

System.Security.Cryp<strong>to</strong>graphy.AsymmetricKeyExchangeDeformatter<br />

System.Security.Cryp<strong>to</strong>graphy.AsymmetricKeyExchangeFormatter<br />

System.Security.Cryp<strong>to</strong>graphy.AsymmetricSignatureDeformatter<br />

System.Security.Cryp<strong>to</strong>graphy.AsymmetricSignatureFormatter<br />

System.Security.Cryp<strong>to</strong>graphy.Cryp<strong>to</strong>APITransform<br />

System.Security.Cryp<strong>to</strong>graphy.Cryp<strong>to</strong>Config<br />

System.Security.Cryp<strong>to</strong>graphy.CspParameters<br />

System.Security.Cryp<strong>to</strong>graphy.DeriveBytes<br />

System.Security.Cryp<strong>to</strong>graphy.FromBase64Transform<br />

System.Security.Cryp<strong>to</strong>graphy.HashAlgorithm<br />

System.Security.Cryp<strong>to</strong>graphy.KeySizes<br />

System.Security.Cryp<strong>to</strong>graphy.MaskGenerationMethod<br />

System.Security.Cryp<strong>to</strong>graphy.RandomNumberGenera<strong>to</strong>r<br />

System.Security.Cryp<strong>to</strong>graphy.SignatureDescription<br />

System.Security.Cryp<strong>to</strong>graphy.SymmetricAlgorithm<br />

System.Security.Cryp<strong>to</strong>graphy.ToBase64Transform<br />

System.Security.Cryp<strong>to</strong>graphy.X509Certificates.X509Certificate<br />

System.Security.Cryp<strong>to</strong>graphy.X509Certificates.X509CertificateCollection.X509CertificateEnumera<strong>to</strong>r<br />

System.Security.Cryp<strong>to</strong>graphy.Xml.DataObject<br />

System.Security.Cryp<strong>to</strong>graphy.Xml.KeyInfo<br />

System.Security.Cryp<strong>to</strong>graphy.Xml.KeyInfoClause<br />

System.Security.Cryp<strong>to</strong>graphy.Xml.Reference<br />

System.Security.Cryp<strong>to</strong>graphy.Xml.Signature<br />

System.Security.Cryp<strong>to</strong>graphy.Xml.SignedInfo<br />

System.Security.Cryp<strong>to</strong>graphy.Xml.SignedXml<br />

System.Security.Cryp<strong>to</strong>graphy.Xml.Transform<br />

System.Security.Cryp<strong>to</strong>graphy.Xml.TransformChain<br />

System.Security.Permissions.PrincipalPermission<br />

System.Security.Permissions.ResourcePermissionBaseEntry<br />

System.Security.Permissions.StrongNamePublicKeyBlob<br />

System.Security.PermissionSet<br />

System.Security.Policy.AllMembershipCondition<br />

System.Security.Policy.ApplicationDirec<strong>to</strong>ry<br />

System.Security.Policy.ApplicationDirec<strong>to</strong>ryMembershipCondition<br />

System.Security.Policy.CodeGroup<br />

Agilent .NET Course: Type and Debugging 16


duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.Security.Policy.Evidence<br />

System.Security.Policy.Hash<br />

System.Security.Policy.HashMembershipCondition<br />

System.Security.Policy.PermissionRequestEvidence<br />

System.Security.Policy.PolicyLevel<br />

System.Security.Policy.PolicyStatement<br />

System.Security.Policy.Publisher<br />

System.Security.Policy.PublisherMembershipCondition<br />

System.Security.Policy.Site<br />

System.Security.Policy.SiteMembershipCondition<br />

System.Security.Policy.StrongName<br />

System.Security.Policy.StrongNameMembershipCondition<br />

System.Security.Policy.Url<br />

System.Security.Policy.UrlMembershipCondition<br />

System.Security.Policy.Zone<br />

System.Security.Policy.ZoneMembershipCondition<br />

System.Security.Principal.GenericIdentity<br />

System.Security.Principal.GenericPrincipal<br />

System.Security.Principal.WindowsIdentity<br />

System.Security.Principal.WindowsImpersonationContext<br />

System.Security.Principal.WindowsPrincipal<br />

System.Security.SecurityElement<br />

System.Security.SecurityManager<br />

System.ServiceProcess.ServiceControllerPermissionEntry<br />

System.String<br />

System.Text.Decoder<br />

System.Text.Encoder<br />

System.Text.Encoding<br />

System.Text.RegularExpressions.Capture<br />

System.Text.RegularExpressions.CaptureCollection<br />

System.Text.RegularExpressions.GroupCollection<br />

System.Text.RegularExpressions.MatchCollection<br />

System.Text.RegularExpressions.Regex<br />

System.Text.RegularExpressions.RegexCompilationInfo<br />

System.Text.StringBuilder<br />

System.Threading.Interlocked<br />

System.Threading.Moni<strong>to</strong>r<br />

System.Threading.ReaderWriterLock<br />

System.Threading.Thread<br />

System.Threading.ThreadPool<br />

System.Threading.Timeout<br />

System.TimeZone<br />

System.UriBuilder<br />

System.ValueType<br />

System.Version<br />

System.WeakReference<br />

System.Web.Caching.Cache<br />

System.Web.Caching.CacheDependency<br />

System.Web.Configuration.HttpCapabilitiesBase<br />

System.Web.Configuration.HttpConfigurationContext<br />

System.Web.Hosting.ApplicationHost<br />

System.Web.HttpApplication<br />

System.Web.HttpCachePolicy<br />

System.Web.HttpCacheVaryByHeaders<br />

System.Web.HttpCacheVaryByParams<br />

Agilent .NET Course: Type and Debugging 17


duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.Web.HttpContext<br />

System.Web.HttpCookie<br />

System.Web.HttpPostedFile<br />

System.Web.HttpRequest<br />

System.Web.HttpResponse<br />

System.Web.HttpRuntime<br />

System.Web.HttpServerUtility<br />

System.Web.HttpStaticObjectsCollection<br />

System.Web.HttpUtility<br />

System.Web.HttpWorkerRequest<br />

System.Web.Mail.MailAttachment<br />

System.Web.Mail.MailMessage<br />

System.Web.Mail.SmtpMail<br />

System.Web.ProcessInfo<br />

System.Web.ProcessModelInfo<br />

System.Web.Security.DefaultAuthenticationModule<br />

System.Web.Security.FileAuthorizationModule<br />

System.Web.Security.FormsAuthentication<br />

System.Web.Security.FormsAuthenticationModule<br />

System.Web.Security.FormsAuthenticationTicket<br />

System.Web.Security.FormsIdentity<br />

System.Web.Security.PassportAuthenticationModule<br />

System.Web.Security.PassportIdentity<br />

System.Web.Security.UrlAuthorizationModule<br />

System.Web.Security.WindowsAuthenticationModule<br />

System.Web.Services.Description.DocumentableItem<br />

System.Web.Services.Description.MimeTextMatch<br />

System.Web.Services.Description.ServiceDescriptionFormatExtension<br />

System.Web.Services.Description.ServiceDescriptionImporter<br />

System.Web.Services.Description.ServiceDescriptionReflec<strong>to</strong>r<br />

System.Web.Services.Description.SoapTransportImporter<br />

System.Web.Services.Discovery.DiscoveryClientPro<strong>to</strong>col.DiscoveryClientResultsFile<br />

System.Web.Services.Discovery.DiscoveryClientResult<br />

System.Web.Services.Discovery.DiscoveryDocument<br />

System.Web.Services.Discovery.DiscoveryReference<br />

System.Web.Services.Discovery.SoapBinding<br />

System.Web.Services.Pro<strong>to</strong>cols.LogicalMethodInfo<br />

System.Web.Services.Pro<strong>to</strong>cols.SoapExtension<br />

System.Web.Services.Pro<strong>to</strong>cols.SoapHeader<br />

System.Web.Services.Pro<strong>to</strong>cols.SoapMessage<br />

System.Web.Services.Pro<strong>to</strong>cols.WebClientAsyncResult<br />

System.Web.SessionState.HttpSessionState<br />

System.Web.SessionState.SessionStateModule<br />

System.Web.TraceContext<br />

System.Web.UI.AttributeCollection<br />

System.Web.UI.BaseParser<br />

System.Web.UI.Control<br />

System.Web.UI.ControlBuilder<br />

System.Web.UI.ControlCollection<br />

System.Web.UI.CssStyleCollection<br />

System.Web.UI.DataBinder<br />

System.Web.UI.DataBinding<br />

System.Web.UI.DataBindingCollection<br />

System.Web.UI.Design.ColorBuilder<br />

System.Web.UI.Design.ControlParser<br />

Agilent .NET Course: Type and Debugging 18


duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.Web.UI.Design.ControlPersister<br />

System.Web.UI.Design.DataBindingHandler<br />

System.Web.UI.Design.DesignTimeData<br />

System.Web.UI.Design.UrlBuilder<br />

System.Web.UI.HtmlControls.HtmlTableCellCollection<br />

System.Web.UI.HtmlControls.HtmlTableRowCollection<br />

System.Web.UI.LosFormatter<br />

System.Web.UI.Pair<br />

System.Web.UI.PropertyConverter<br />

System.Web.UI.StateBag<br />

System.Web.UI.StateItem<br />

System.Web.UI.Triplet<br />

System.Web.UI.Valida<strong>to</strong>rCollection<br />

System.Web.UI.WebControls.CalendarDay<br />

System.Web.UI.WebControls.DataGridColumn<br />

System.Web.UI.WebControls.DataGridColumnCollection<br />

System.Web.UI.WebControls.DataGridItemCollection<br />

System.Web.UI.WebControls.DataKeyCollection<br />

System.Web.UI.WebControls.DataListItemCollection<br />

System.Web.UI.WebControls.DayRenderEventArgs<br />

System.Web.UI.WebControls.FontInfo<br />

System.Web.UI.WebControls.ListItem<br />

System.Web.UI.WebControls.ListItemCollection<br />

System.Web.UI.WebControls.MonthChangedEventArgs<br />

System.Web.UI.WebControls.PagedDataSource<br />

System.Web.UI.WebControls.RepeaterItemCollection<br />

System.Web.UI.WebControls.RepeatInfo<br />

System.Web.UI.WebControls.SelectedDatesCollection<br />

System.Web.UI.WebControls.TableCellCollection<br />

System.Web.UI.WebControls.TableRowCollection<br />

System.Windows.Forms.AmbientProperties<br />

System.Windows.Forms.Application<br />

System.Windows.Forms.ApplicationContext<br />

System.Windows.Forms.AxHost.State<br />

System.Windows.Forms.Binding<br />

System.Windows.Forms.BindingContext<br />

System.Windows.Forms.BindingManagerBase<br />

System.Windows.Forms.CheckedListBox.CheckedIndexCollection<br />

System.Windows.Forms.CheckedListBox.CheckedItemCollection<br />

System.Windows.Forms.Clipboard<br />

System.Windows.Forms.ComboBox.ObjectCollection<br />

System.Windows.Forms.Control.ControlCollection<br />

System.Windows.Forms.ControlPaint<br />

System.Windows.Forms.CreateParams<br />

System.Windows.Forms.Cursor<br />

System.Windows.Forms.Cursors<br />

System.Windows.Forms.DataFormats<br />

System.Windows.Forms.DataFormats.Format<br />

System.Windows.Forms.DataGrid.HitTestInfo<br />

System.Windows.Forms.DataObject<br />

System.Windows.Forms.Design.AxImporter<br />

System.Windows.Forms.Design.AxImporter.Options<br />

System.Windows.Forms.Design.PropertyTab<br />

System.Windows.Forms.FeatureSupport<br />

System.Windows.Forms.GridItem<br />

Agilent .NET Course: Type and Debugging 19


duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.Windows.Forms.GridItemCollection<br />

System.Windows.Forms.Help<br />

System.Windows.Forms.ImageList.ImageCollection<br />

System.Windows.Forms.ImageListStreamer<br />

System.Windows.Forms.InputLanguage<br />

System.Windows.Forms.LinkLabel.Link<br />

System.Windows.Forms.LinkLabel.LinkCollection<br />

System.Windows.Forms.ListBox.ObjectCollection<br />

System.Windows.Forms.ListBox.SelectedIndexCollection<br />

System.Windows.Forms.ListBox.SelectedObjectCollection<br />

System.Windows.Forms.ListView.CheckedIndexCollection<br />

System.Windows.Forms.ListView.CheckedListViewItemCollection<br />

System.Windows.Forms.ListView.ColumnHeaderCollection<br />

System.Windows.Forms.ListView.ListViewItemCollection<br />

System.Windows.Forms.ListView.SelectedIndexCollection<br />

System.Windows.Forms.ListView.SelectedListViewItemCollection<br />

System.Windows.Forms.ListViewItem<br />

System.Windows.Forms.ListViewItem.ListViewSubItem<br />

System.Windows.Forms.ListViewItem.ListViewSubItemCollection<br />

System.Windows.Forms.Menu.MenuItemCollection<br />

System.Windows.Forms.MessageBox<br />

System.Windows.Forms.MonthCalendar.HitTestInfo<br />

System.Windows.Forms.PropertyGrid.PropertyTabCollection<br />

System.Windows.Forms.Screen<br />

System.Windows.Forms.ScrollableControl.DockPaddingEdges<br />

System.Windows.Forms.SelectionRange<br />

System.Windows.Forms.SendKeys<br />

System.Windows.Forms.StatusBar.StatusBarPanelCollection<br />

System.Windows.Forms.SystemInformation<br />

System.Windows.Forms.TabControl.TabPageCollection<br />

System.Windows.Forms.ToolBar.ToolBarBut<strong>to</strong>nCollection<br />

System.Windows.Forms.TreeNodeCollection<br />

System.Xml.Schema.XmlSchemaCollection<br />

System.Xml.Schema.XmlSchemaCollectionEnumera<strong>to</strong>r<br />

System.Xml.Schema.XmlSchemaDatatype<br />

System.Xml.Schema.XmlSchemaObject<br />

System.Xml.Schema.XmlSchemaObjectEnumera<strong>to</strong>r<br />

System.Xml.Schema.XmlSchemaObjectTable<br />

System.Xml.Serialization.SoapAttributeOverrides<br />

System.Xml.Serialization.SoapAttributes<br />

System.Xml.Serialization.XmlAttributeOverrides<br />

System.Xml.Serialization.XmlAttributes<br />

System.Xml.Serialization.XmlSerializer<br />

System.Xml.Serialization.XmlSerializerNamespaces<br />

System.Xml.XmlConvert<br />

System.Xml.XmlImplementation<br />

System.Xml.XmlNamedNodeMap<br />

System.Xml.XmlNamespaceManager<br />

System.Xml.XmlNameTable<br />

System.Xml.XmlNode<br />

System.Xml.XmlNodeChangedEventArgs<br />

System.Xml.XmlNodeList<br />

System.Xml.XmlParserContext<br />

System.Xml.XmlQualifiedName<br />

System.Xml.XmlReader<br />

Agilent .NET Course: Type and Debugging 20


System.Xml.XmlResolver<br />

System.Xml.XmlWriter<br />

System.Xml.XPath.XPathDocument<br />

System.Xml.XPath.XPathExpression<br />

System.Xml.XPath.XPathNaviga<strong>to</strong>r<br />

System.Xml.XPath.XPathNodeItera<strong>to</strong>r<br />

System.Xml.Xsl.XsltArgumentList<br />

System.Xml.Xsl.XslTransform<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: Type and Debugging 21


Name:<br />

Course: <strong>Intro</strong>duction <strong>to</strong> .NET<br />

Title: Module 5<br />

Instruc<strong>to</strong>r: Andrew Cumming<br />

.NET


5 Day 3 am<br />

5.1 Contents<br />

Morning session<br />

• Methods and overloaded methods, Intellisense<br />

• Exceptions<br />

• Using Namespaces<br />

• Using Modules and Assemblies<br />

• Using non‐visual components<br />

• Using regular expressions<br />

• Searching help<br />

• Creating and Using Delegates<br />

• Defining and Using Events<br />

Afternoon<br />

• <strong>Intro</strong>ducing Cerebus<br />

• The Agilent TM Limit components<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: Module 5, page 2


5.2 Overloaded Methods<br />

An overloaded method is one that has more than one pattern of parameters.<br />

Consider the method MessageBox.Show<br />

The Show method is overloaded 12 times. Two of these overloadings are shown below:<br />

Signatures for MessageBox.Show<br />

public static DialogResult Show(<br />

string text<br />

);<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

public static DialogResult Show(<br />

string text,<br />

string caption,<br />

MessageBoxBut<strong>to</strong>ns but<strong>to</strong>ns,<br />

MessageBoxIcon icon<br />

);<br />

At it’s simplest we might use just one parameter:<br />

Simple use of MessageBox.Show()<br />

MessageBox.Show("Make my day.");<br />

In a more complex situation we include a caption, a question icon and specify two<br />

but<strong>to</strong>ns Yes and No. Moreover we make use of the return value.<br />

A Less simple use of MessageBox.Show()<br />

if (MessageBox.Show("Do you feel lucky",<br />

"Clint asks:",<br />

System.Windows.Forms.MessageBoxBut<strong>to</strong>ns.YesNo,<br />

System.Windows.Forms.MessageBoxIcon.Question)<br />

== System.Windows.Forms.DialogResult.Yes)<br />

Console.WriteLine("Bang");<br />

else<br />

Console.WriteLine("You have the right <strong>to</strong> remain silent...");<br />

We get a list of the overloading in the edi<strong>to</strong>r – when this box pops up we can run<br />

through the options using the up and down arrow keys.<br />

Agilent .NET Course: Module 5, page 3


5.3 Creating overloaded methods<br />

We can create overloaded methods ourselves very simply. We need only repeat the<br />

definition, but with a different parameter list.<br />

Care should be takes with this – it is considered good practice if each overloading<br />

performs essentially the same task. The MessageBox.Show is an excellent example<br />

of good practice (if rather excessive in have 12 options).<br />

• The same method can be used “quick‐and‐dirty” and “careful” users.<br />

• Sensible default values are given when parameters are left unspecified.<br />

During development of code we often find that we need <strong>to</strong> generalise. We start with<br />

a simple method and find that it needs <strong>to</strong> be more complex.<br />

The designers of MessageBox might have started with the notion of a simple alert<br />

box that <strong>to</strong>ok a single string – they then found that their users required more and<br />

more control.<br />

Using overloading it is possible <strong>to</strong> publish a simple component then expand on it.<br />

The advantage of this is that existing code that uses the simple interface does not<br />

have <strong>to</strong> be re‐written when the new version of the class is released.<br />

To avoid duplication of code we often have one “base” implementation that the others<br />

call. The based should be the “largest” overloading – the one with the most<br />

parameters.<br />

5.4 Overloaded Method Example<br />

The Country class records details of a single country – name, region, area, population<br />

and gdp.<br />

When the population increases (when a baby is born for example) we want <strong>to</strong> increment<br />

the population. The method <strong>to</strong> do this is called IncPop.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Examples of the definition of an overloaded method<br />

public void IncPop(int increment)<br />

{<br />

this.population += increment;<br />

}<br />

public void IncPop()<br />

{<br />

IncPop(1);<br />

}<br />

Agilent .NET Course: Module 5, page 4


5.5 Contributing <strong>to</strong> Intellisense<br />

We can comment our code so that out comments pop up in the intellisense pane.<br />

Examples of the definition of an overloaded method<br />

///<br />

///Increase the population of this country<br />

///<br />

///Number of new people<br />

public void IncPop(<br />

int increment)<br />

{<br />

this.population += increment;<br />

}<br />

Comments need <strong>to</strong> be in xml tags such as or .<br />

The tags must be in the triple stroke comments <strong>to</strong> be processed.<br />

The comments should immediately precede the declaration line.<br />

See the help section “Recommended Tags for Documentation Comments”.<br />

5.6 Exceptions<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

C# uses exceptions <strong>to</strong> deal with run time errors.<br />

We protect areas of code that can possibly generate exceptions using a try block –<br />

we must add a catch block and we may add a finally block.<br />

Examples of Exceptions 3.2.1<br />

Console.WriteLine("Test started.");<br />

try<br />

{<br />

StreamReader fs = new StreamReader("c:\\nosuchfile.txt");<br />

Console.WriteLine("The file stream has been opened.");<br />

string s=fs.ReadLine();<br />

Console.WriteLine("A line of text has been read.");<br />

}<br />

catch<br />

{<br />

Console.WriteLine("An exception was raised.");<br />

}<br />

finally<br />

{<br />

Console.WriteLine("Finished.");<br />

}<br />

Console.WriteLine("Test completed.");<br />

Agilent .NET Course: Module 5, page 5


In the above example (assuming that the file c:\sosuchfile.txt does no exist) we get<br />

the following output:<br />

Output of Exceptions 3.2.2<br />

Test started.<br />

An exception was raised.<br />

Finished.<br />

Test completed.<br />

The exception will be raised at the “new StreamReader” line – the following line<br />

does not get executed, instead execution jumps <strong>to</strong> the catch block, then the finally<br />

block then continues with the code outside the try/catch/finally structure.<br />

Without the try blocks the whole method will fail and the stack will unwind.<br />

There are different exceptions for different conditions.<br />

Examples of Exceptions 3.2.3<br />

System.NullReferenceException<br />

System.DivideByZeroException<br />

System.InvalidCastException<br />

System.IO.FileNotFoundException<br />

5.7 Finer control over exceptions<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

A host of different exceptions exist. We can test for a specific exception by including<br />

an exception reference in the catch clause. All exceptions inherit from System.Exception<br />

– this will catch any exception.<br />

We can perform further tests inside the catch block – we can examine ex.GetType()<br />

<strong>to</strong> find out exactly what exception was raised.<br />

Finer control<br />

try<br />

{<br />

DateTime x = (DateTime) new Object();<br />

}<br />

catch (System.InvalidCastException ex)<br />

{<br />

MessageBox.Show("The cast was invalid");<br />

}<br />

catch (Exception ex)<br />

{<br />

MessageBox.Show("Some kind of error happened :^(\n"+<br />

ex.ToString());<br />

}<br />

Agilent .NET Course: Module 5, page 6


5.8 Throwing Exceptions<br />

We may deliberately choose <strong>to</strong> cause an exception. We use the throw statement for<br />

this.<br />

We may define our own Exceptions and throw them.<br />

Choose one or neither of the below:<br />

• There is no point in doing this unless we carefully document the circumstances.<br />

If we cannot be bothered <strong>to</strong> do this we should not bother creating<br />

cus<strong>to</strong>m exceptions.<br />

• Exceptions are self‐documenting mechanisms. It is bad practice <strong>to</strong> throw<br />

someone else’s exception.<br />

5.9 Policy on when <strong>to</strong> catch and when <strong>to</strong> throw<br />

The business of which exceptions <strong>to</strong> catch is complex. There are often good reasons<br />

<strong>to</strong> not catch exceptions. An uncaught exception will propagate back up the stack.<br />

• The Cerebus system has a mechanism for dealing with exceptions.<br />

• Comment from Nick<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: Module 5, page 7


5.10 Using non-visual components<br />

We can import components on<strong>to</strong> our form at design time. These have properties<br />

that we can conveniently <strong>set</strong> at design time.<br />

An example of such a component is the file browser.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

The non‐visual components can have their properties <strong>set</strong> conveniently at design<br />

time. The code <strong>to</strong> declare these components (globally <strong>to</strong> the project) are included<br />

au<strong>to</strong>matically – as is the code <strong>to</strong> <strong>set</strong> the design time property values.<br />

We can use these controls in code.<br />

Using OpenFileDialog<br />

if (System.Windows.Forms.DialogResult.OK<br />

== openFileDialog1.ShowDialog())<br />

{<br />

string s= openFileDialog1.FileName ;<br />

MessageBox.Show(s);<br />

}<br />

Agilent .NET Course: Module 5, page 8


5.11 Regular Expressions<br />

Use of regular expressions can simplify much of the hard work of string processing.<br />

We can specify patterns that get matched against input strings.<br />

Some simple patterns:<br />

Simple Patterns<br />

.<br />

Matches any character<br />

\s<br />

Matches any white space character<br />

\S<br />

Matches any non white space characters<br />

\d<br />

Matches any digit<br />

and<br />

Matches the word and<br />

.*<br />

Matches any number of any characters – "greedy" match<br />

^<br />

Matches the beginning of the search string<br />

$<br />

Matches the end of the search string<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Because we make use of the \ character regular expressions are almost always defined<br />

using @ʺ.<br />

Simple Patterns<br />

Regex re = new Regex(@"^B.*land");<br />

StreamReader sr = new StreamReader(@"..\..\ciaTabbed.txt");<br />

while (sr.Peek()>0)<br />

{<br />

string s = sr.ReadLine();<br />

if (re.Match(s).Success)<br />

Console.WriteLine(s);<br />

}<br />

The above section of code searches for strings that start with B and include ʺlandʺ<br />

Matches for ^B.*land<br />

Baker Island Oceania 1.4 0<br />

Bouvet Island Antarctic Region 58.5 0<br />

British Virgin Islands Central America and the Caribbean 150 19615 287000000<br />

5.11.1 Extracting substrings using Regular Expressions<br />

We can include brackets in our patterns and obtain the contents of these.<br />

Agilent .NET Course: Module 5, page 9


The pattern @ʺ^(.*), Theʺ will match countries such as ʺBahamas, Theʺ. We can extract<br />

the contents of the brackets by looking at structure Match or MatchCollection.<br />

5.11.2 Match<br />

Commonly we are only interested in one <strong>set</strong> of matches.<br />

If this is the case we can use the Match object. We can get<br />

Extracting substrings<br />

Regex populationPattern = new Regex(@"Population: (\S*)");<br />

while (sr.Peek()>0)<br />

{<br />

string s = sr.ReadLine();<br />

Match m = populationPattern.Match(s);<br />

if (m.Success)<br />

{<br />

MessageBox.Show(m.Groups[1].Value);<br />

}<br />

}<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

5.11.3 MatchCollection<br />

The match collection contains a list of lists. Commonly there is only one item in the<br />

list. This item consists of the whole matching string followed by each of the brackets<br />

in order.<br />

Extracting substrings<br />

Regex re = new Regex(@"^(.*), (The)\t");<br />

StreamReader sr = new StreamReader(@"..\..\ciaTabbed.txt");<br />

while (sr.Peek()>0)<br />

{<br />

string s = sr.ReadLine();<br />

MatchCollection m = re.Matches(s);<br />

if (m.Count>0)<br />

{<br />

Console.WriteLine(s);<br />

Console.WriteLine("item 0,0:" + m[0].Groups[0]);<br />

Console.WriteLine("item 0,1:" + m[0].Groups[1]);<br />

Console.WriteLine("item 0,2:" + m[0].Groups[2]);<br />

}<br />

}<br />

Output extracting substrings<br />

Bahamas, The Central America and the Caribbean 13940 294982 5580000000<br />

item 0,0:Bahamas, The<br />

item 0,1:Bahamas<br />

item 0,2:The<br />

Gambia, The Africa 11300 1367124 1400000000<br />

item 0,0:Gambia, The<br />

item 0,1:Gambia<br />

item 0,2:The<br />

Agilent .NET Course: Module 5, page<br />

10


The following problem appeared as ENIGMA 1168 in New Scientist<br />

5.12 THRICE UNFACTORISED<br />

5.12.1 Richard England<br />

I have found a four‐digit number such that it is impossible<br />

<strong>to</strong> fac<strong>to</strong>rise the numbers formed by its first digit or last<br />

digit or first two digits or middle two digits or last two<br />

digits or first three digits or last three digits or all four digits.<br />

In other words all those eight numbers are prime<br />

except that either or both of the single‐digit numbers may<br />

be unity.<br />

Harry and Tom have also found such a four‐digit number.<br />

The four‐digit numbers that we have found are all different;<br />

but Harryʹs number uses the same digits as Tomʹs<br />

number, though in a different order. Which four‐digit<br />

number have I found<br />

http://www.cs.bris.ac.uk/~edwards/maths/primes.html<br />

http://www.utm.edu/research/primes/lists/small/1000.txt<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: Module 5, page<br />

11


5.13 Exceptions Tu<strong>to</strong>rial<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Tasks.<br />

1) Try the Megalomania solution. Observe that we have a Class file Country and a<br />

user interface Megalomania. We will try <strong>to</strong> keep the two parts of the system<br />

separate. Observe the action of two existing but<strong>to</strong>ns.<br />

2) Trivial change <strong>to</strong> the user interface:<br />

a) Add a new label <strong>to</strong> the project.<br />

b) Change the action of the ʺUpdate worldLBʺ but<strong>to</strong>n so that the new label shows<br />

a count of the number of items in worldLB. (worldLB.Items.Count contains<br />

the number you need).<br />

c) Check that the change works.<br />

3) Trivial change <strong>to</strong> Country.cs:<br />

a) Change the ToString method <strong>to</strong> include some more spaces in the format<br />

string. This should make the text box contents easier on the eye.<br />

4) Break the data 1:<br />

a) Edit the file ciaFixedWidth.txt so that it includes a country with a non‐numeric<br />

where a numeric value is expected. For example<br />

ʺAndrew Land Europe 0 1 nixʺ<br />

Observe that a run time error occurs when you try <strong>to</strong> load the file.<br />

b) Enclose a section of code in a try block so that processing continues and such<br />

duff lines are ignored.<br />

c) Report the error by writing an appropriate message using the System.Diagnostics.Trace.WriteLine<br />

method.<br />

5) Break the data 2:<br />

a) Change the file name of ciaFixedWidth.txt so that a different run time error is<br />

generated.<br />

b) Trap this error with a wider try block. We cannot continue with the routine after<br />

such an error <strong>to</strong> an alert should be generated with an appropriate<br />

MessageBox with an appropriate icon.<br />

6) Generalise the file open procedure:<br />

a) Allow the user <strong>to</strong> specify the location of the CIA file – use the open file dialog<br />

control.<br />

b) For the purposes of the next question you must ensure that the file dialog<br />

permits you <strong>to</strong> enter files that do not exist and illegal file names. You need <strong>to</strong><br />

change three properties <strong>to</strong> allow this.<br />

7) Allow some exceptions <strong>to</strong> be unhandled.<br />

a) We want <strong>to</strong> ensure that only the ʺFile not foundʺ exception is caught. If the<br />

Agilent .NET Course: Module 5, page<br />

12


user enters an illegal filename (such as ʺ6:abcʺ) we want the exception <strong>to</strong> go<br />

uncaught – in the debug environment the debugger starts.<br />

i) Identify the exception we want <strong>to</strong> catch (you can <strong>set</strong> a breakpoint and<br />

use the local window for this).<br />

ii) Ensure the catch is specific <strong>to</strong> this exception only.<br />

iii) Check your program completes successfully when given a good file<br />

name.<br />

iv) Check your program gives a fatal warning when given a file that does<br />

not exist.<br />

v) Check that your program generates an unhandled exception when given<br />

an illegal file name.<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: Module 5, page<br />

13


5.14 Regular Expressions Tu<strong>to</strong>rial<br />

8) Open the project Regular. This application reads files taken from the CIA world<br />

factbook and extracts features of a single country. Source files for United Kingdom,<br />

France and Algeria are available in the project as uk.txt, fr.txt and ag.txt.<br />

a) Execute the project and note that only the population details have been extracted.<br />

b) Find the routine that performs the search. Use the break command <strong>to</strong> terminate<br />

the loop once a successful match has been found.<br />

9) The field Region appears on lines such as ʺMap references: Europeʺ. Create a<br />

regular expression that finds such lines and extracts the required data.<br />

10) With a little investigation you should find that name, the area and the GDP<br />

could be extracted in a similar way. Note the following:<br />

a) The name of the country appears at several places – you may choose any that<br />

is convenient.<br />

b) The GDP may be in millions or billions or trillions.<br />

11) We want <strong>to</strong> exclude the commas from the numbers. We may use the static<br />

method Regex.Replace <strong>to</strong> remove commas.<br />

12) (Extra hard question – requires MatchCollection) Use the line ʺPolitical Parties<br />

and leaders:ʺ <strong>to</strong> extract and print a list of parties.<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: Module 5, page<br />

14


5.15 Methods Tu<strong>to</strong>rial<br />

We return <strong>to</strong> the Megalomania solution for this tu<strong>to</strong>rial. We will be creating methods<br />

<strong>to</strong> process the Country class. In each case we should create methods in the<br />

Country.cs file and call them from the interface.<br />

13) Create routines <strong>to</strong> increment the population as in the lecture notes.<br />

a) Create a but<strong>to</strong>n that increments the population of country index 5. Implement<br />

IncPop so that the following code can be attached <strong>to</strong> a new but<strong>to</strong>n on the<br />

form:<br />

Country target = ((Country)world[5]);<br />

target.IncPop(1000000);<br />

You should notice the population of Angola go from about 10 million <strong>to</strong><br />

about 11 million.<br />

b) Create the method Annex – this country adds in all of the population, area and<br />

gdp of the victim country. The victim country still exists but with an area,<br />

population and gdp of zero. Attach the following code <strong>to</strong> a new but<strong>to</strong>n and<br />

observe what happens <strong>to</strong> Jersey and the Isle of Man.<br />

private void but<strong>to</strong>n2_Click(object sender, System.EventArgs e)<br />

{<br />

Country uk = (Country) world[248];<br />

Country jersey = (Country)world[121];<br />

Country iom = (Country)world[150];<br />

uk.Annex(jersey);<br />

uk.Annex(iom);<br />

}<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

c) Create the + opera<strong>to</strong>r (See chapter 6 of Jesse Liberty). This is opera<strong>to</strong>r creates a<br />

new country with the combined population, gdp and area of the two participants.<br />

The name of the new country should be <strong>set</strong> <strong>to</strong> “New Country”. The<br />

region should be <strong>set</strong> – if the two countries are in different regions an exception<br />

should be raised. Create a but<strong>to</strong>n <strong>to</strong> unite North and South Korea with<br />

the following code:<br />

private void but<strong>to</strong>n3_Click(object sender, System.EventArgs e)<br />

{<br />

Country northKorea = (Country)world[129];<br />

Country southKorea = (Country)world[130];<br />

world.Add(northKorea+southKorea);<br />

}<br />

d) You should find the new country at the bot<strong>to</strong>m of the list.<br />

Agilent .NET Course: Module 5, page<br />

15


5.16 Sorting and Interfaces<br />

We return <strong>to</strong> the Megalomania solution for this tu<strong>to</strong>rial. We examine how we may<br />

use the Sort method.<br />

14) Attempt <strong>to</strong> sort the ArrayList world.<br />

a) Add a new but<strong>to</strong>n on the interface.<br />

b) Make the code behind the but<strong>to</strong>n a simple statement world.Sort();<br />

c) This should compile but fail at run time.<br />

d) To make the Sort work we need <strong>to</strong> implement the IComparable interface –<br />

the first step is <strong>to</strong> change the class declaration:<br />

public class Country : IComparable<br />

e) The code should now fail <strong>to</strong> compile – by insisting that Country satisfies the<br />

IComparable interface we are claiming that it has the signature of IComparable.<br />

f) Fortunately IComparable has a very simple signature – it simply requires that<br />

there exist a method int CompareTo(obj Object) – this should return –1 or 0<br />

or 1 depending on how this compares <strong>to</strong> obj. This is the comparison made<br />

for sorting.<br />

g) Implement the method and observe the sort.<br />

h) <strong>Intro</strong>duce another but<strong>to</strong>n <strong>to</strong> allow sorting by population – descending. Page<br />

199 of Jesse Liberty’s book has the details.<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: Module 5, page<br />

16


Name:<br />

Course: <strong>Intro</strong>duction <strong>to</strong> .NET<br />

Title: Module 6<br />

Instruc<strong>to</strong>r: Andrew Cumming<br />

.NET


6 Day 3 pm<br />

6.1 Contents<br />

Morning session<br />

• Methods and overloaded methods, intellisense<br />

• Exceptions<br />

• Using Namespaces<br />

• Using Modules and Assemblies<br />

• Using non‐visual components<br />

• Using regular expressions<br />

• Searching help<br />

• Creating and Using Delegates<br />

• Defining and Using Events<br />

Afternoon<br />

• <strong>Intro</strong>ducing Cerebus<br />

• The Agilent TM Limit components<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: Module 6, page 2


6.2 Cerebus<br />

The run time environment provides the<br />

facilities <strong>to</strong> select the test dll and the test<br />

sequence.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

We can select the dll from open and execute it using run.<br />

Agilent .NET Course: Module 6, page 3


6.3 Adding Limit Checkers<br />

We can open the Limits collection and add any of a variety of Limit Checker components.<br />

The properties of these components can be <strong>set</strong> at design time. We use the Check()<br />

method <strong>to</strong> perform the tests.<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: Module 6, page 4


protected override void UserRun()<br />

{<br />

// TODO: Do the Test task here: perform the measurement and<br />

limit checking<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

Trace.WriteLine(new TmTraceEntry(this,<br />

TmTraceSwitch.TestSwitch,<br />

TmTraceLevel.Verbose,<br />

"starting testpoint"));<br />

MessageBox.Show("training example");<br />

singleSidedLimit1.Check(-1);<br />

Thread.Sleep(2000);<br />

singleSidedLimit2.Check(-1);<br />

powerMeter.re<strong>set</strong>();<br />

Trace.WriteLine(new TmTraceEntry(this,<br />

TmTraceSwitch.TestSwitch,<br />

TmTraceLevel.Verbose,<br />

"ending testpoint"));<br />

Agilent .NET Course: Module 6, page 5


6.4 Tu<strong>to</strong>rial<br />

Starting with the AgilentTrainingFiles example complete the following tasks.<br />

1) Execute the program from the test environment.<br />

a) Observe the successful completion of the test sequence.<br />

b) Make a note of the three messages that show up in the Log tab. The final message<br />

should read “ending testpoint”<br />

2) Make a trivial change <strong>to</strong> the code:<br />

a) View the code of the TrainingTest.cs.<br />

b) Find the method UserRun and note that the two Trace lines give the same<br />

message.<br />

c) Change the second Trace line so that it produces “ending testpoint”.<br />

3) The powerMeter object is available within the TrainingTest.cs, include a call <strong>to</strong><br />

the re<strong>set</strong> method after the first trace statement. powerMeter.re<strong>set</strong>() should do the<br />

trick – notice the new line in the Log produced by this call.<br />

4) Create a new method in the power meter class.<br />

a) The method should be called blink<br />

b) It should write an appropriate message <strong>to</strong> the log using Trace.WriteLine.<br />

c) Observe the Log for the new test.<br />

5) Update the training sequence so that the test is run 3 times. You can do this by<br />

editing the file TrainingTest_DrivingData.csv repeat the final line (use a different<br />

name in the extra lines).<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: Module 6, page 6


Name:<br />

Course: <strong>Intro</strong>duction <strong>to</strong> .NET<br />

Title: Objects<br />

Instruc<strong>to</strong>r: <strong>Bill</strong> <strong>Buchanan</strong><br />

.NET


7 Objects<br />

7.1 <strong>Intro</strong>duction<br />

This module covers the key elements of arrays, indexers and collections. It covers:<br />

• Classes and objects. This revises the material covered in Module 1.<br />

• Using encapsulation.<br />

• Defining Object‐Oriented Systems.<br />

• Inheritance.<br />

• Abstract classes.<br />

• Sealed classes.<br />

• Overriding classes.<br />

7.2 Classes and objects<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

We live in a world full of objects; so object‐oriented programming is a natural technique<br />

in developing programs. For example, we have an object called a cup, and<br />

each cup has a number of properties, such as its colour, its shape, its size, and so on.<br />

It is efficient for us <strong>to</strong> identify it as a cup, as we know that cups should be able <strong>to</strong><br />

hold liquid, and we will place our cup beside all the other cups that we have. If we<br />

were a cup designer then we could list all the possible properties of a cup, and for<br />

each design, we could <strong>set</strong> the properties of the cup. Of course, some of the properties<br />

might not actually be used, but for a general‐purpose design, we would specify<br />

every property that a cup might have. For example, in a simple case we could have<br />

the following properties:<br />

Properties Cup 1 Cup 2 Cup3<br />

Shape (Standard/Square/Mug) Standard Square Mug<br />

Colour (Red/Blue/Green) Blue Red Green<br />

Size (Small/Medium/Large) Small Large Small<br />

Transparency (0 <strong>to</strong> 100%) 100% 50% 25%<br />

Handle type (Small/Large) Small Small Large<br />

Thus, we have three choices of shape (square, standard or mug), three choices of<br />

colour (red, blue or green), three choices in size (small, medium or large) and two<br />

Agilent .NET Course: Objects 2


choices of handle type (small or large). In addition, we can also choose a level of<br />

transparency of the cup from 0 <strong>to</strong> 100% (in integer steps). In object‐oriented program,<br />

the collection of properties is known as a class. Thus, we could have a class<br />

for our cup which encapsulates all the design parameters for our cup. The instance<br />

of our class, such as Cup 1, Cup 2 and Cup 3, are known as objects. We can create<br />

many objects from our class. Along with this, there are certain things that we want<br />

<strong>to</strong> do with the cup, such as picking it up, painting it, or even dropping it. In objec<strong>to</strong>rientation,<br />

these are known as methods, and are the functions that can be allowed<br />

<strong>to</strong> operate on our objects.<br />

Program 7.1 shows an object‐oriented example of the cup, where a class named<br />

Cup is created, of which an instance is named cup. A full description on this program<br />

will be discussed in a later module. It uses variables, such as Shape, Colour, and Size<br />

<strong>to</strong> define the property of an object.<br />

Program 7.1: Program1_1_ClassSimpleCup<br />

using System;<br />

namespace ConsoleApplication2<br />

{<br />

public class Cup<br />

{<br />

public string Shape;<br />

public string Colour;<br />

public string Size;<br />

public int Transparency;<br />

public string Handle;<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

public void DisplayCup()<br />

{<br />

System.Console.WriteLine("Cup is {0}, {1}", Colour, Handle);<br />

}<br />

}<br />

class Class1<br />

{<br />

static void Main(string[] args)<br />

{<br />

Cup cup = new Cup();<br />

cup.Colour = "Red"; cup.Handle = "Small";<br />

cup.DisplayCup();<br />

cup.Colour = "Green"; cup.Handle = "Small";<br />

cup.DisplayCup();<br />

System.Console.ReadLine();<br />

}<br />

}<br />

}<br />

Sample Run<br />

Cup is Red, Small<br />

Cup is Green, Small<br />

In the following example, we create a class named Circuit, of which we create a<br />

new instance of it named cir. The class then has two methods, named Serial and<br />

Parallel.<br />

Agilent .NET Course: Objects 3


Program 7.2:<br />

using System;<br />

namespace ConsoleApplication2<br />

{<br />

public class Circuit<br />

{<br />

public string name;<br />

}<br />

public double Parallel(double r1, double r2)<br />

{<br />

return((r1*r2)/(r1+r2));<br />

}<br />

public double Series(double r1, double r2)<br />

{<br />

return(r1+r2);<br />

}<br />

class Class1<br />

{<br />

static void Main(string[] args)<br />

{<br />

double v1=100,v2=100;<br />

double res;<br />

Circuit cir = new Circuit();<br />

cir.name="Circuit 1";<br />

res=cir.Parallel(v1,v2);<br />

System.Console.WriteLine("[{0}] Parallel resistance is {1} ohms",<br />

cir.name,res);<br />

cir.name="Circuit 2";<br />

res=cir.Series(v1,v2);<br />

System.Console.WriteLine("[{0}] Series resistance is {1} ohms ",<br />

cir.name,res);<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

System.Console.ReadLine();<br />

}<br />

}<br />

}<br />

Sample Run<br />

[Circuit 1] Parallel resistance is 50 ohms<br />

[Circuit 2] Series resistance is 200 ohms<br />

In this case, we have used a single object (cir). Of course, we could have created<br />

two objects, with:<br />

Circuit cir1 = new Circuit();<br />

Circuit cir2 = new Circuit();<br />

cir1.name="Circuit 1"; res1=cir1.Parallel(v1,v2);<br />

cir2.name="Circuit 2"; res2=cir.Series(v1,v2);<br />

Agilent .NET Course: Objects 4


Finally, for this section, Program 7.3 shows an example of a complex number class,<br />

where a complex number object is created (r), which is made up of two components<br />

(r.real and r.imag). The class defines two methods: mag() and angle(), which calculate<br />

the magnitude and the angle of the complex number, using:<br />

z = x + jy<br />

z<br />

z<br />

=<br />

x<br />

2<br />

= tan<br />

+ y<br />

−1<br />

⎛<br />

⎜<br />

⎝<br />

2<br />

y<br />

x<br />

⎞<br />

⎟<br />

⎠<br />

Program 7.3:<br />

using System;<br />

namespace ConsoleApplication2<br />

{<br />

public class Complex<br />

{<br />

public double real;<br />

public double imag;<br />

public double mag()<br />

{<br />

return (Math.Sqrt(real*real+imag*imag));<br />

}<br />

public double angle()<br />

{<br />

return (Math.Atan(imag/real)*180/Math.PI);<br />

}<br />

}<br />

class Class1<br />

{<br />

static void Main(string[] args)<br />

{<br />

string str;<br />

double mag,angle;<br />

Complex r = new Complex();<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

}<br />

System.Console.Write("Enter real value >>");<br />

str=System.Console.ReadLine();<br />

r.real = Convert.ToInt32(str);<br />

System.Console.Write("Enter imag value >>");<br />

str=System.Console.ReadLine();<br />

r.imag = Convert.ToInt32(str);<br />

mag=r.mag();<br />

angle=r.angle();<br />

System.Console.WriteLine("Mag is {0} and angle is {1}",mag,angle);<br />

System.Console.ReadLine();<br />

}<br />

Sample Run<br />

Enter real value >> 3<br />

Enter imag value >> 4<br />

Mag is 5 and angle is 53.130102354156<br />

Agilent .NET Course: Objects 5


7.3 Using encapsulation<br />

Properties are useful techniques in defined the state of a class. For example, a car<br />

might have the following properties:<br />

• Make. This could be Ford, Vauxhall, Nissan or Toyota.<br />

• Type. This could be Vectra, Astra, or Mondeo.<br />

• Colour. This could be colours such as Red, Green or Blue.<br />

• Country of Manufacture. This could be countries such as UK, Germany or<br />

France.<br />

Normally in object‐oriented programs, the variable members of the class are not<br />

make public, thus we can defined a property which can be used <strong>to</strong> <strong>set</strong> these variables.<br />

Program 7.4 shows an example where the variables make, type, colour and<br />

country are made private, but properties are defined for these, in order <strong>to</strong> <strong>set</strong> them.<br />

Program 7.4:<br />

using System;<br />

namespace sample01<br />

{<br />

public class Car<br />

{<br />

private string colour;<br />

private string type;<br />

private string make;<br />

private string country;<br />

private double cost;<br />

public string Colour<br />

{<br />

get { return colour; }<br />

<strong>set</strong> { colour=value; }<br />

}<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

public string Type<br />

{<br />

get { return type; }<br />

<strong>set</strong> { type=value; }<br />

}<br />

public string Country<br />

{<br />

get { return country; }<br />

<strong>set</strong> { country=value; }<br />

}<br />

public string Make<br />

{<br />

get { return make; }<br />

<strong>set</strong> { make=value; }<br />

}<br />

public double Cost<br />

{<br />

get { return cost; }<br />

<strong>set</strong> { cost=value; }<br />

}<br />

Agilent .NET Course: Objects 6


}<br />

class Class1<br />

{<br />

static void Main(string[] args)<br />

{<br />

Car car1 = new Car();<br />

}<br />

}<br />

car1.Colour="Red";<br />

car1.Make="Ford";<br />

car1.Type="Mondeo";<br />

car1.Colour="UK";<br />

car1.Cost=15000;<br />

Console.WriteLine("Car is a " + car1.Make + " " + car1.Type);<br />

Console.ReadLine();<br />

}<br />

Sample Run<br />

Car is a Ford Mondeo<br />

It can be seen that the properties defines a <strong>set</strong> and get definitions. These are named<br />

the get and <strong>set</strong> accessors, and are similar <strong>to</strong> methods. The get accessor reads the<br />

value of the field, while the <strong>set</strong> accessor reads its value. In most cases, the .NET environment<br />

senses the use of the property and shows the options for it as the user<br />

types the statement, such as:<br />

duction <strong>to</strong> .NET<br />

The value part of the <strong>set</strong> in Program 7.4 defines that the value from the property<br />

which is <strong>set</strong> is taken from. For example:<br />

public double Cost<br />

{<br />

get { return cost; }<br />

<strong>set</strong> { cost=value; }<br />

}<br />

The value of cost will take the value from object.Cost.<br />

<strong>Intro</strong><br />

Agilent .NET Course: Objects 7


7.3.1 Read-only fields<br />

A property with only a get accessor is read‐only, whereas a property with only a<br />

<strong>set</strong> is write‐only. If it has both a <strong>set</strong> and get assess it is a read/write property. It is<br />

important <strong>to</strong> encapsulate the class correctly so that the objects cannot be accessed in<br />

an incorrect way. For example if we change the Cost property <strong>to</strong> make it read‐only:<br />

public double Cost<br />

{<br />

get { return cost; }<br />

}<br />

and try <strong>to</strong> use it:<br />

car1.Cost=15000;<br />

The builder will return an error of:<br />

Property or indexer 'sample01.Car.Cost' cannot be assigned <strong>to</strong> -- it is read<br />

only<br />

But, we could use it, such as:<br />

Console.WriteLine("The cost is " + car1.Cost);<br />

7.4 Defining Object-Oriented Systems<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Classes exist within a structure and interlink with others. For example if we think<br />

animals we can group them animals in<strong>to</strong> a generalisation, which has a common behaviour<br />

and characteristics. We could then sub‐divide mammals up in<strong>to</strong> different<br />

classifications, such cats, dog and horses (as illustrated in Figure 7.1). From there we<br />

can further subdivide until we get <strong>to</strong> actual species. Thus we generalise at the <strong>to</strong>p of<br />

the hierarchy, and specialise as we move down it. In object‐orient techniques, we<br />

create a hierarchy such as this, which starts with generalised class, which then future<br />

sub‐divide in<strong>to</strong> specialisations. In C# the <strong>to</strong>p level is System namespace, which<br />

has certain splits of in<strong>to</strong> other namespaces, such as Windows, IO, and Drawing, as<br />

illustrated in Figure 7.2. Below System.Windows is System.Windows.Forms,<br />

which has a number of classes assigned <strong>to</strong> it. These include:<br />

• Form. To add a form.<br />

• TextBox. Which creates a textbox.<br />

• ComboBox. Which creats a combobox.<br />

• ScrollBar. Which creates a scrollbar.<br />

Agilent .NET Course: Objects 8


Mammals<br />

Increasing<br />

generalisation<br />

Cats Cats<br />

Dogs Dogs<br />

Horses Horses<br />

Lion Lion<br />

Tiger Tiger<br />

Domestic<br />

Shared<br />

behaviours<br />

and<br />

characteristics<br />

Increasing<br />

specialisation<br />

Figure 7.1: Animal classifications<br />

containers<br />

System System<br />

Increasing<br />

generalisation<br />

Windows<br />

IO IO<br />

Drawing<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Component<br />

Component<br />

Model<br />

Model<br />

Design Design<br />

Forms Forms<br />

Label Label<br />

Combo Combo<br />

Box Box<br />

But<strong>to</strong>n But<strong>to</strong>n<br />

Form Form<br />

Class<br />

Figure 7.2: Object hierarchy in C#<br />

Increasing<br />

specialisation<br />

Agilent .NET Course: Objects 9


Thus, we can say that a But<strong>to</strong>n is a kind of Forms (excuse the poor use of English,<br />

though). Program 7.5 shown an example program with a form, a textbox and a but<strong>to</strong>n.<br />

It can be seen that the form is defined as a class with:<br />

Derived class<br />

public class Form1 : System.Windows.Forms.Form<br />

Base class<br />

which means that our form derives from System.Windows.Forms.Form. The<br />

but<strong>to</strong>n and the text box are defined with:<br />

private System.Windows.Forms.But<strong>to</strong>n but<strong>to</strong>n1;<br />

private System.Windows.Forms.TextBox textBox1;<br />

Which means they derive from System.Windows.Forms.But<strong>to</strong>n and System.Windows.Forms.TextBox,<br />

respectively.<br />

Program 7.5:<br />

using System.Collections;<br />

using System.ComponentModel;<br />

using System.Windows.Forms;<br />

using System.Data;<br />

namespace WindowsApplication3<br />

{<br />

public class Form1 : System.Windows.Forms.Form<br />

{<br />

private System.Windows.Forms.But<strong>to</strong>n but<strong>to</strong>n1;<br />

private System.Windows.Forms.TextBox textBox1;<br />

Base class<br />

public Form1() { InitializeComponent(); }<br />

private void InitializeComponent()<br />

{<br />

this.but<strong>to</strong>n1 = new System.Windows.Forms.But<strong>to</strong>n();<br />

this.textBox1 = new System.Windows.Forms.TextBox();<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

this.but<strong>to</strong>n1.Location = new System.Drawing.Point(152, 192);<br />

this.but<strong>to</strong>n1.Name = "but<strong>to</strong>n1";<br />

this.but<strong>to</strong>n1.TabIndex = 0;<br />

this.but<strong>to</strong>n1.Text = "but<strong>to</strong>n1";<br />

this.textBox1.Location = new System.Drawing.Point(80, 64);<br />

this.textBox1.Name = "textBox1";<br />

this.textBox1.TabIndex = 1;<br />

this.textBox1.Text = "textBox1";<br />

this.Controls.Add(this.textBox1);<br />

this.Controls.Add(this.but<strong>to</strong>n1);<br />

this.Name = "Form1";<br />

this.Text = "Form1";<br />

this.Load += new System.EventHandler(this.Form1_Load);<br />

this.ResumeLayout(false);<br />

Agilent .NET Course: Objects 10


}<br />

}<br />

static void Main()<br />

{<br />

Application.Run(new For m1());<br />

}<br />

private void Form1_Load(object sender, System.EventArgs e)<br />

{<br />

// event for the loading of the form<br />

}<br />

7.4.1 Inheritance<br />

Inheritance is a key fac<strong>to</strong>r in C#, where derived classes inherit all the members of<br />

the base classes. In Program 7.6 a class named People is created. This has a property<br />

of name, and a method of ToLowerCase(). Next a Profile class is created,<br />

which derives from People. Profile thus inherits all the members of People.<br />

Program 7.6:<br />

using System;<br />

namespace ConsoleApplication1<br />

{<br />

class People<br />

{<br />

private string name;<br />

}<br />

public string Name {<br />

get {return name;}<br />

<strong>set</strong> {name=value;}<br />

}<br />

public void ToLowerCase()<br />

{<br />

name=name.ToLower();<br />

}<br />

People<br />

Profile Profile<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

class Profile : People<br />

{ // Inherit from People<br />

public void Display()<br />

{<br />

Console.WriteLine("Name: "+Name);<br />

}<br />

}<br />

class Test<br />

{<br />

static void Main()<br />

{<br />

Profile p1 = new Profile();<br />

p1.Name="Fred";<br />

p1.ToLowerCase();<br />

p1.Display();<br />

Method inherited<br />

from People<br />

Agilent .NET Course: Objects 11


System.Console.ReadLine();<br />

}<br />

}<br />

}<br />

Sample Run<br />

Name: fred<br />

If we now change the class <strong>to</strong>:<br />

class Test<br />

{<br />

static void Main()<br />

{<br />

Profile p1 = new Profile();<br />

Profile p2 = new Profile();<br />

p1.Name="Fred";<br />

p2.Name="Bert";<br />

}<br />

}<br />

p1.ToLowerCase();<br />

p1.Display();<br />

p2.Display();<br />

System.Console.ReadLine();<br />

Then the output will become:<br />

Name: fred<br />

Name: Bert<br />

Where the first name (Fred) has had the ToLowerCase() method applied <strong>to</strong> it, but<br />

the second one (Bert) has not.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

7.5 Sealed classes<br />

The sealed modifier is used <strong>to</strong> bar classes from deriving its members, and is used <strong>to</strong><br />

prevent deviation from the original purposes of a class. For example, if in Program<br />

7.6 we change the People class <strong>to</strong>:<br />

sealed class People<br />

{<br />

private string name;<br />

public string Name {<br />

get {return name;}<br />

<strong>set</strong> {name=value;}<br />

}<br />

Agilent .NET Course: Objects 12


}<br />

public void ToLowerCase()<br />

{<br />

name=name.ToLower();<br />

}<br />

When the program is now built an error messages is displayed:<br />

'ConsoleApplication1.Profile' : cannot inherit from sealed class<br />

'ConsoleApplication1.People'<br />

7.6 Overriding classes<br />

Sometimes a developer might want <strong>to</strong> implement their own methods. This could be<br />

<strong>to</strong> enhance the operation of the method, or <strong>to</strong> refine it for a certain application or<br />

system. For this the override keyword is used <strong>to</strong> identify that a method overrides a<br />

method from the base class. An example in Program 7.7 shows that the overriding<br />

class is defined with:<br />

public override void ToLowerCase()<br />

{<br />

Console.WriteLine("Method has been overwritten");<br />

}<br />

and the virtual keyword is used in the definition of the method in the base class,<br />

such as:<br />

public virtual void ToLowerCase()<br />

{<br />

name=name.ToLower();<br />

}<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Program 7.7:<br />

using System;<br />

namespace ConsoleApplication1<br />

{<br />

class People<br />

{<br />

private string name;<br />

public string Name<br />

{<br />

get {return name;}<br />

<strong>set</strong> {name=value;}<br />

}<br />

public virtual void ToLowerCase()<br />

{<br />

name=name.ToLower();<br />

Agilent .NET Course: Objects 13


}<br />

}<br />

class Profile : People<br />

{ // Inherit from People<br />

public void Display()<br />

{<br />

Console.WriteLine("Name: "+Name);<br />

}<br />

public override void ToLowerCase()<br />

{<br />

Console.WriteLine("Method has been overwritten");<br />

}<br />

}<br />

class Test<br />

{<br />

static void Main()<br />

{<br />

Profile p1 = new Profile();<br />

p1.Name="Fred";<br />

p1.ToLowerCase();<br />

p1.Display();<br />

System.Console.ReadLine();<br />

}<br />

}<br />

}<br />

Sample Run<br />

Method has been overwritten<br />

Name: Fred<br />

Every class derives from the Object, of which the main methods are:<br />

duction <strong>to</strong> .NET<br />

• Equals(). Determines if two objects are the same.<br />

• Finalize(). Cleans up the object (the destruc<strong>to</strong>r).<br />

• GetHashCode(). Allows an object <strong>to</strong> define its hash code.<br />

• GetType(). Determine the type of an object.<br />

• MemberwiseClone(). Create a copy of the object.<br />

• ReferenceEquals(). Determines whether two objects are of the same instance.<br />

• ToString(). Convert an object <strong>to</strong> a string.<br />

It can be seen from Figure 7.3 that some of these methods have been derive from the<br />

main object model. As an example, we can override these methods for any object<br />

that is created.<br />

<strong>Intro</strong><br />

Agilent .NET Course: Objects 14


Program 7.8:<br />

using System;<br />

namespace ConsoleApplication1<br />

{<br />

class People<br />

{<br />

private string name;<br />

Figure 7.3: Example of object method<br />

}<br />

public string Name<br />

{<br />

get {return name;}<br />

<strong>set</strong> {name=value;}<br />

}<br />

public virtual void ToLowerCase()<br />

{<br />

name=name.ToLower();<br />

}<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

class Profile : People<br />

{ // Inherit from People<br />

public void Display()<br />

{<br />

Console.WriteLine("Name: "+Name);<br />

}<br />

}<br />

public override string ToString()<br />

{<br />

return("Cannot implement this method");<br />

}<br />

class Test<br />

{<br />

static void Main()<br />

{<br />

Profile p1 = new Profile();<br />

Agilent .NET Course: Objects 15


p1.Name="Fred";<br />

string str=p1.ToString();<br />

Console.WriteLine(str);<br />

System.Console.ReadLine();<br />

}<br />

}<br />

}<br />

Sample Run<br />

Method has been overwritten<br />

Name: Fred<br />

7.7 Abstract classes<br />

There are times in programming<br />

Okay. Okay. It’s It’s<br />

when the developer of a class wants<br />

worth worth it. it.<br />

I’ll<br />

Here<br />

<strong>to</strong> force the classes which derive the<br />

Here is is the<br />

I’ll do do that. that.<br />

the<br />

new new class, class, but but you you<br />

can’t<br />

class <strong>to</strong> write their own methods.<br />

can’t use use it it unless unless you you<br />

implement your your own own<br />

OpenTheBox()<br />

This might be where a system could<br />

method!<br />

use different types of graphics displays,<br />

and that the developer should<br />

write their own implementation of a<br />

DrawWindow() method. An abstract<br />

class can be used for this,<br />

where the class contains an abstract<br />

definition of the format of the At times a new class must be forced <strong>to</strong> create a new<br />

method. In C# it is not possible <strong>to</strong> derive a class if there is not an implementation of<br />

an abstract method contained in it.<br />

For example if we have an abstract class for a Car:<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

public abstract class Car<br />

{<br />

public abstract void ShowColour();<br />

public abstract void ShowType();<br />

}<br />

This defines that the deriving class must implement these methods. As it is an abstract<br />

class, there is no implementation as this is up <strong>to</strong> the derived class <strong>to</strong><br />

implement it. Using the previous example, we can force the derived class (Profile) <strong>to</strong><br />

implement the DisplayLower() method with the addition of the line:<br />

public abstract void DisplayLower();<br />

in the People class.<br />

Agilent .NET Course: Objects 16


Program 7.9:<br />

using System;<br />

namespace ConsoleApplication1<br />

{<br />

class People<br />

{<br />

private string name;<br />

}<br />

public string Name<br />

{<br />

get {return name;}<br />

<strong>set</strong> {name=value;}<br />

}<br />

public void ToLowerCase()<br />

{<br />

name=name.ToLower();<br />

}<br />

public abstract void DisplayLower();<br />

class Profile : People<br />

{ // Inherit from People<br />

public void Display()<br />

{<br />

Console.WriteLine("Name: "+Name);<br />

}<br />

}<br />

class Test<br />

{<br />

static void Main()<br />

{<br />

Profile p1 = new Profile();<br />

p1.Name="Fred";<br />

p1.ToLowerCase();<br />

p1.Display();<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

}<br />

}<br />

System.Console.ReadLine();<br />

The builder will give the following error:<br />

'ConsoleApplication1.Profile' does not implement inherited abstract<br />

member 'ConsoleApplication1.People.DisplayLower()'<br />

To overcome this we would have <strong>to</strong> add the following method:<br />

Agilent .NET Course: Objects 17


public override void DisplayLower()<br />

{<br />

Console.WriteLine("Name: "+Name.ToUpper());<br />

}<br />

which will implement the required method. Program 7.10 shows the full implementation<br />

of the program.<br />

Program 7.10:<br />

using System;<br />

namespace ConsoleApplication1<br />

{<br />

abstract class People<br />

{<br />

private string name;<br />

}<br />

public string Name<br />

{<br />

get {return name;}<br />

<strong>set</strong> {name=value;}<br />

}<br />

public void ToLowerCase()<br />

{<br />

name=name.ToLower();<br />

}<br />

abstract public void DisplayLower();<br />

class Profile : People<br />

{ // Inherit from People<br />

public void Display()<br />

{<br />

Console.WriteLine("Name: "+Name);<br />

}<br />

public override void DisplayLower()<br />

{<br />

Console.WriteLine("Name: "+Name.ToUpper());<br />

}<br />

}<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

class Test<br />

{<br />

static void Main()<br />

{<br />

Profile p1 = new Profile();<br />

}<br />

}<br />

p1.Name="Fred";<br />

p1.ToLowerCase();<br />

p1.Display();<br />

p1.DisplayLower();<br />

System.Console.ReadLine();<br />

Agilent .NET Course: Objects 18


Sample Run<br />

Name: fred<br />

Name: FRED<br />

Obviously, the developer does not actually need <strong>to</strong> put anything in the implementation<br />

of the code, if they do not want <strong>to</strong>. For this, they can create an empty method.<br />

public override void DisplayLower() { }<br />

<strong>Intro</strong><br />

duction <strong>to</strong> .NET<br />

Agilent .NET Course: Objects 19


Name:<br />

Course: <strong>Intro</strong>duction <strong>to</strong> .NET<br />

Title: More Objects<br />

Instruc<strong>to</strong>r: <strong>Bill</strong> <strong>Buchanan</strong><br />

.NET


8 More Objects<br />

8.1 <strong>Intro</strong>duction<br />

This module covers the key elements of arrays, indexers and collections. It covers:<br />

• Interfaces.<br />

• Construc<strong>to</strong>rs.<br />

• Destruc<strong>to</strong>rs.<br />

• Static and instance members.<br />

• Practical example.<br />

8.2 Interfaces<br />

An interface is an alternative method of creating an abstract, but it does not contain<br />

any implementation of the methods, at all. It provides a base class for all the derived<br />

classes. For example, in Figure 8.1 we have a circuit which can either have a series or<br />

a parallel resistance.<br />

Series circuit: R T<br />

= R 1<br />

+ R2<br />

Parallel circuit:<br />

R1<br />

⋅ R2<br />

R T<br />

=<br />

R + R<br />

1<br />

2<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Circuit<br />

R T<br />

= R 1<br />

+ R2<br />

r 1 r 2<br />

r 1<br />

r 2<br />

R ⋅ R2<br />

R<br />

1<br />

R T<br />

=<br />

R1<br />

+<br />

Figure 8.1: Circuit with series and parallel resistance<br />

2<br />

Agilent .NET Course: More Objects 2


An interface can be created for this circuit <strong>to</strong> define the components of the circuit<br />

(r1 and r2), and the method (calcParallel() and calcSeries()) with:<br />

interface NewCircuit<br />

{<br />

double r1 { <strong>set</strong>; get;}<br />

double r2 { <strong>set</strong>; get;}<br />

double calcParallel();<br />

double calcSeries();<br />

}<br />

which defines that the base class has two properties and two methods. The derived<br />

class can then be defined with:<br />

public class Circuit: NewCircuit<br />

{<br />

private double res1, res2;<br />

}<br />

public double r1<br />

{<br />

<strong>set</strong> { res1=value;}<br />

get { return res1; }<br />

}<br />

public double r2<br />

{<br />

<strong>set</strong> { res2=value;}<br />

get { return res2; }<br />

}<br />

public double calcParallel()<br />

{<br />

return((r1*r2)/(r1+r2));<br />

}<br />

public double calcSeries()<br />

{<br />

return(r1+r2);<br />

}<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

and called with:<br />

Circuit cir = new Circuit();<br />

cir.r1=1000;<br />

cir.r2=1000;<br />

double res = cir.calcParallel();<br />

The full program is given in Program 8.1<br />

Agilent .NET Course: More Objects 3


Program 8.1:<br />

using System;<br />

interface NewCircuit<br />

{<br />

double r1 { <strong>set</strong>; get;}<br />

double r2 { <strong>set</strong>; get;}<br />

double calcParallel();<br />

double calcSeries();<br />

}<br />

public class Circuit: NewCircuit<br />

{<br />

private double res1, res2;<br />

public double r1<br />

{<br />

<strong>set</strong> { res1=value;}<br />

get { return res1; }<br />

}<br />

public double r2<br />

{<br />

<strong>set</strong> { res2=value;}<br />

get { return res2; }<br />

}<br />

public double calcParallel()<br />

{<br />

return((r1*r2)/(r1+r2));<br />

}<br />

public double calcSeries()<br />

{<br />

return(r1+r2);<br />

}<br />

}<br />

public class Class1<br />

{<br />

static void Main()<br />

{<br />

Circuit cir = new Circuit();<br />

duction <strong>to</strong> .NET<br />

cir.r1=1000;<br />

cir.r2=1000;<br />

double res = cir.calcParallel();<br />

System.Console.WriteLine("Parallel Resistance is " + res);<br />

System.Console.ReadLine();<br />

}<br />

}<br />

Sample Run<br />

Parallel Resistance is 500<br />

An interface is defined with a special symbol. Figure 8.2 shows some sample interfaces.<br />

In this case the interfaces are:<br />

<strong>Intro</strong><br />

Agilent .NET Course: More Objects 4


• IOCollection. Defines size, enumera<strong>to</strong>rs and synchronization methods for all<br />

collections. The public properties are: Count, IsSynchronized and SyncRoot, and<br />

a method of CopyTo().<br />

• IComparer. Compares two objects. The associated method is Compare().<br />

• IEnumera<strong>to</strong>r. Supports iteration over a collection. The properties are Current,<br />

and the methods are MoveNext() and Re<strong>set</strong>().<br />

• IList. Represents a collection of objects that are accessed by an index. The properties<br />

are IsFixedSize, IsReadOnly, Item, and the methods are: Add(), Clear(),<br />

Contains(), IndexOf(), Insert(), Remove() and RemoveAt().<br />

The classes which implement IOCollection include:<br />

• Array.<br />

• ArrayList.<br />

• Hastable.<br />

Thus an array will have the following properties:<br />

• Count.<br />

• IsSynchronized.<br />

• SyncRoot<br />

And a method of:<br />

• CopyTo().<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Figure 8.2: Sample interfaces<br />

Agilent .NET Course: More Objects 5


8.2.1 Combining interfaces<br />

New interaces can be created by combining two of more base interfaces. For example,<br />

based on the previous example, we can add another interface which defines a<br />

calcDifference() method:<br />

interface NewCircuit<br />

{<br />

double r1 { <strong>set</strong>; get;}<br />

double r2 { <strong>set</strong>; get;}<br />

double calcParallel();<br />

double calcSeries();<br />

}<br />

interface NewCircuit2<br />

{<br />

double calcDifference();<br />

}<br />

These interfaces can be merged with:<br />

interface NewCircuitTotal : NewCircuit, NewCircuit2<br />

{}<br />

Then the class is derived with:<br />

public class Circuit: NewCircuitTotal<br />

{<br />

private double res1, res2;<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

public double r1<br />

{<br />

<strong>set</strong> { res1=value;}<br />

get { return res1; }<br />

}<br />

public double r2<br />

{<br />

<strong>set</strong> { res2=value;}<br />

get { return res2; }<br />

}<br />

public void Setr2(double r)<br />

{<br />

r2=r;<br />

}<br />

public double calcParallel()<br />

{<br />

return((r1*r2)/(r1+r2));<br />

}<br />

public double calcSeries()<br />

{<br />

return(r1+r2);<br />

}<br />

public double calcDifference()<br />

{<br />

return(r1-r2);<br />

Agilent .NET Course: More Objects 6


}<br />

}<br />

The complete code is given in Program 8.2<br />

Program 8.2:<br />

using System;<br />

using System.Collections;<br />

interface NewCircuit<br />

{<br />

double r1 { <strong>set</strong>; get;}<br />

double r2 { <strong>set</strong>; get;}<br />

double calcParallel();<br />

double calcSeries();<br />

}<br />

interface NewCircuit2<br />

{<br />

double calcDifference();<br />

}<br />

interface NewCircuitTotal : NewCircuit, NewCircuit2<br />

{}<br />

public class Circuit: NewCircuitTotal<br />

{<br />

private double res1, res2;<br />

public double r1<br />

{<br />

<strong>set</strong> { res1=value;}<br />

get { return res1; }<br />

}<br />

public double r2<br />

{<br />

<strong>set</strong> { res2=value;}<br />

get { return res2; }<br />

}<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

public void Setr2(double r)<br />

{<br />

r2=r;<br />

}<br />

public double calcParallel()<br />

{<br />

return((r1*r2)/(r1+r2));<br />

}<br />

public double calcSeries()<br />

{<br />

return(r1+r2);<br />

}<br />

public double calcDifference()<br />

{<br />

return(r1-r2);<br />

}<br />

}<br />

public class Class1<br />

Agilent .NET Course: More Objects 7


{<br />

static void Main()<br />

{<br />

Circuit cir = new Circuit();<br />

cir.r1=1000;<br />

cir.r2=1000;<br />

double res = cir.calcDifference();<br />

System.Console.WriteLine("Parallel Resistance is " + res);<br />

System.Console.ReadLine();<br />

}<br />

}<br />

Sample Run<br />

Parallel Resistance is 500<br />

It can be seen in Figure 8.3 that the method has been derived in the object.<br />

Figure 8.3: Derived classes<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

8.3 Construc<strong>to</strong>rs<br />

A construc<strong>to</strong>r is a method which is au<strong>to</strong>matically called when the object of created.<br />

This is useful in initially <strong>set</strong>ting values <strong>to</strong> an object. It is defined within the class<br />

with the same name as class. For example <strong>to</strong> initialize a previous example if we had<br />

a class named Profile, then the construc<strong>to</strong>r within the class will also be named Profile,<br />

such as:<br />

public Profile(string c)<br />

{<br />

code=c;<br />

}<br />

public string Name<br />

{<br />

Agilent .NET Course: More Objects 8


}<br />

<strong>set</strong> { name=value; }<br />

get { return name; }<br />

}<br />

public string Telephone<br />

{<br />

<strong>set</strong> { telephone=value; }<br />

get { return telephone; }<br />

}<br />

public void Display()<br />

{<br />

Console.WriteLine("Code: " + code +<br />

" Name: " + name + " Telephone: " + telephone);<br />

Console.ReadLine();<br />

}<br />

The construc<strong>to</strong>r, in this case, can be called by passing a string in<strong>to</strong> the new object,<br />

such as:<br />

Profile pf1=new Profile("00000");<br />

Program 8.3 shows a complete program.<br />

Program 8.3:<br />

using System;<br />

namespace ConsoleApplication5<br />

{<br />

class Profile<br />

{<br />

string code, name, telephone;<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

// Construc<strong>to</strong>r<br />

public Profile(string c)<br />

{<br />

code=c;<br />

}<br />

public string Name<br />

{<br />

<strong>set</strong> { name=value; }<br />

get { return name; }<br />

}<br />

public string Telephone<br />

{<br />

<strong>set</strong> { telephone=value; }<br />

get { return telephone; }<br />

}<br />

public void Display()<br />

{<br />

Console.WriteLine("Code: " + code + " Name: " +<br />

name + " Telephone: " + telephone);<br />

Console.ReadLine();<br />

}<br />

Agilent .NET Course: More Objects 9


class Class1<br />

{<br />

static void Main(string[] args)<br />

{<br />

Profile pf1=new Profile("00000");<br />

pf1.Name="Fred Smith";<br />

pf1.Telephone="123456";<br />

pf1.Display();<br />

}<br />

}<br />

}<br />

Sample Run<br />

Code: 00000 Name: Fred Smith Telephone: 123456<br />

8.4 Destruc<strong>to</strong>rs<br />

A destruc<strong>to</strong>rs is the opposite of a construc<strong>to</strong>r, and occur when an object is deleted. It<br />

is defined in the class with:<br />

~ClassName()<br />

{<br />

// Destruc<strong>to</strong>r coce<br />

}<br />

For example in the previous example we could have added:<br />

~Profile()<br />

{<br />

Console.WriteLine("Getting rid of object .. " + this.ToString());<br />

}<br />

To display when the objects were deleted.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

8.5 Static and Instance Members<br />

A class can either have static members of instance members. Instance members relate<br />

<strong>to</strong> the object created, while static members can be used by referring <strong>to</strong> the name<br />

of the method within the class. For example the following are calls <strong>to</strong> static members:<br />

Convert.ToInteger("str");<br />

Console.WriteLine("Hello");<br />

Whereas in the following, there are two instance methods (Read() and Write()),<br />

Agilent .NET Course: More Objects 10


these operate on the created data type:<br />

System.IO.StreamReader nn = new StreamReader();<br />

nn.Read();<br />

nn.Write();<br />

Static members thus operate on an instance of a class.<br />

Along with static member, it is possible <strong>to</strong> create static variables. These are often<br />

used <strong>to</strong> keep track of the number of instances of a class. An example is shown in<br />

Program 8.4 where a static member variable of numberProfile is created <strong>to</strong> count<br />

the number of instances of the class. This is part of the class, and not part of any instance<br />

of it.<br />

Program 8.4:<br />

using System;<br />

namespace ConsoleApplication5<br />

{<br />

class Profile<br />

{<br />

static int numberProfile=0;<br />

string code, name, telephone;<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

// Construc<strong>to</strong>r<br />

public Profile(string c)<br />

{<br />

numberProfile++;<br />

code=c;<br />

}<br />

public string Name<br />

{<br />

<strong>set</strong> { name=value; }<br />

get { return name; }<br />

}<br />

public string Telephone<br />

{<br />

<strong>set</strong> { telephone=value; }<br />

get { return telephone; }<br />

}<br />

public void Display()<br />

{<br />

Console.WriteLine("Code: " + code + " Name: " + name +<br />

" Telephone: " + telephone);<br />

Console.ReadLine();<br />

}<br />

public static void HowMany()<br />

{<br />

Console.WriteLine("There are " + numberProfile + " profiles ");<br />

Console.ReadLine();<br />

}<br />

Agilent .NET Course: More Objects 11


class Class1<br />

{<br />

static void Main(string[] args)<br />

{<br />

Profile pf1=new Profile("00000");<br />

pf1.Name="Fred Smith"; pf1.Telephone="123456";<br />

Profile pf2=new Profile("00001");<br />

pf2.Name="Fred Cannon"; pf2.Telephone="223456";<br />

Profile pf3=new Profile("00002");<br />

pf3.Name="Fred McDonald"; pf3.Telephone="323456";<br />

Profile.HowMany();<br />

}<br />

}<br />

}<br />

Sample Run<br />

There are 3 profiles<br />

<strong>Intro</strong><br />

duction <strong>to</strong> .NET<br />

Agilent .NET Course: More Objects 12


8.6 IIInstrument example<br />

///copyright agilent technologies 2003<br />

///filename: IInstrumentMeasModule.cs<br />

///author: Nick McALonan<br />

///date: Oct 2003<br />

///change his<strong>to</strong>ry -<br />

///module testing his<strong>to</strong>ry -<br />

///description - This file is the Measurement level public I/F for generic<br />

instrument calls<br />

///and as such the implemeation should be contained within each measurement<br />

module project that requires it.<br />

using System;<br />

namespace Agilent.Sqf.Of.Instrument<br />

{<br />

///copyright agilent technologies 2003<br />

///filename: IInstrumentMeasModule.cd<br />

///author: NickMcALonan<br />

///date: Oc<strong>to</strong>ber 2003<br />

///change his<strong>to</strong>ry -<br />

///module testing his<strong>to</strong>ry -<br />

///description - This file is the Measurement level public I/F for generic<br />

instrument calls<br />

///and as such contains only declarations of the methods that applly at ALL<br />

instruments.<br />

///This interface should be ///inherited by all other measurement interfaces<br />

public interface IInstrumentMeasModule<br />

{<br />

void QueryFirmware(out string Firmware);<br />

void Re<strong>set</strong>();<br />

}<br />

}<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

using System;<br />

namespace Agilent.Sqf.Of.PPMC<br />

{<br />

/// <br />

/// Summary description for IPPMCInstrument.<br />

/// <br />

public interface IPPMCInstrument<br />

{<br />

int StartUpPPMC(int comPort);<br />

void RebootPPMC(int comPort);<br />

void SetupPPMCParams(int comPort, string pathToFirmware, string<br />

downloadParamsFile);<br />

void DownloadFirmware(string pathToFirmware, string downloadFilename);<br />

void UpdateBootSettings(string pathToFirmware, string bootFileInfo);<br />

}<br />

}<br />

///copyright agilent technologies 2003<br />

///filename: IPowerMeterMeasModule.cs<br />

///author: Steve Welsh<br />

Agilent .NET Course: More Objects 13


date: September 2003<br />

///change his<strong>to</strong>ry -<br />

///module testing his<strong>to</strong>ry -<br />

///description - This file is the Measurement level public I/F for PowerMeterMeasImp.cs<br />

///and as such contains only declarations of the methods defined within the<br />

implementation<br />

///<br />

using System;<br />

//using agilent.sqf.of.common_enums;<br />

using Agilent.Sqf.Of.Common_enums;<br />

using Agilent.Sqf.Of.Instrument;<br />

using System.Collections;<br />

namespace Agilent.Sqf.Of.PowerMeter<br />

{<br />

public interface IPowerMeterMeasModule<br />

:Agilent.Sqf.Of.Instrument.IInstrumentMeasModule,<br />

Agilent.Sqf.Of.PPMC.IPPMCInstrument<br />

{<br />

void CalibratePowerMeter(CommonEnums.CHANNEL Channel,<br />

CommonEnums.CALIBRATE ZeroOrAu<strong>to</strong>);<br />

void SetRefPortState(bool On);<br />

double MeasurePower(CommonEnums.POWER_MEAS_TYPE MeasType,<br />

CommonEnums.CHANNEL PrimaryChannel, CommonEnums.CHANNEL<br />

SecondaryChannel);<br />

}<br />

}<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: More Objects 14


Name:<br />

Course: <strong>Intro</strong>duction <strong>to</strong> .NET<br />

Title: Module 10<br />

Instruc<strong>to</strong>r: Andrew Cumming<br />

.NET


10 Day 5 pm<br />

10.1 Contents<br />

Morning session<br />

• 1 mW Test<br />

Afternoon<br />

• More on Sorting<br />

• Events and Delegates<br />

• Attributes<br />

• Review<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: Module 10,page 2


10.2 Implementing an interface<br />

In Module 3 we saw that <strong>to</strong> use the Sort() method on our ArrayList world we had <strong>to</strong><br />

implement the IComparable interface in the Country class.<br />

This is achieved with two steps:<br />

1. Include the restriction : IComparable in the declaration of the Country class<br />

2. Fill in the method .CompareTo(Object obj) in the Country class.<br />

Code <strong>to</strong> allow Sort of an ArrayList of Country<br />

public class Country : IComparable<br />

. . .<br />

#region IComparable Members<br />

/// <br />

/// Compare two countries by name<br />

/// <br />

/// The other country<br />

/// <br />

public int CompareTo(object obj)<br />

{<br />

return this.Name.CompareTo(((Country) obj).Name);<br />

}<br />

#endregion<br />

In order <strong>to</strong> sort by another field (for example population) we must use a different<br />

overloading of the Sort method.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

public virtual void Sort(<br />

IComparer comparer<br />

);<br />

Despite the similar name IComparer has a different signature. It requires exactly<br />

one method Compare:<br />

int Compare(<br />

object x,<br />

object y<br />

);<br />

Agilent .NET Course: Module 10,page 3


We can create the required method in the user interface – this involves creating an<br />

“empty” class.<br />

Code <strong>to</strong> allow Sort of an ArrayList of Country<br />

private class PopComparer : IComparer<br />

{<br />

int IComparer.Compare(Object x, Object y )<br />

{<br />

//x and y are both countries.<br />

//We must return...<br />

// -1 if population of x is less than population of y<br />

// 0 if populations are equal<br />

// 1 otherwise<br />

throw new Exception("Not implemented yet!");<br />

return 0;<br />

}<br />

}<br />

private void SortPop_Click(object sender, System.EventArgs e)<br />

{<br />

world.Sort(new PopComparer());<br />

}<br />

In this code we are creating object simply <strong>to</strong> satisfy interfaces.<br />

<strong>Intro</strong>duction <strong>to</strong> .NET<br />

Agilent .NET Course: Module 10,page 4


10.3 Review of terms<br />

For each of the following terms give an example from the Megalomania code or<br />

elsewhere:<br />

Term Example Explanation<br />

Class<br />

Namespace<br />

Parameter<br />

Method<br />

Accessor<br />

private property<br />

public method<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

override<br />

method<br />

ArrayList<br />

Construc<strong>to</strong>r<br />

Agilent .NET Course: Module 10,page 5


10.4 Any Others<br />

Term Example Explanation<br />

<strong>Intro</strong><br />

duction <strong>to</strong> .NET<br />

Agilent .NET Course: Module 10,page 6


10.5 Hiding members<br />

We can hide the properties of our classes so that they may not be directly accessed.<br />

Many object‐oriented practitioners regard this as good practice.<br />

Before protection<br />

public class Country<br />

{<br />

public string name;<br />

public string region=null;<br />

public int area=-1;<br />

public int population=-1;<br />

public long gdp=-1;<br />

After protection<br />

public class Country<br />

{<br />

private string name;<br />

private string region;<br />

private int area;<br />

private int population;<br />

private long gdp;<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

public string Name{get{return this.name;}}<br />

public string Region{get{return this.region;}}<br />

public int Area{get{return this.area;}}<br />

public int Population<br />

{<br />

get{return this.population;}<br />

<strong>set</strong>{this.population=value;}<br />

}<br />

public long Gdp{get{return this.gdp;}}<br />

In this case have hidden the private members – they can only be accessed from<br />

within the Class. We have exposed members with slightly different names. From<br />

outside the class we may refer <strong>to</strong> uk.Name but not uk.name (where uk is a Country).<br />

Also we have made most of these exposed properties read only.<br />

The Population member is writeable – this means we can assign uk.Population just<br />

as we used <strong>to</strong> be able <strong>to</strong> do.<br />

Which of these is permitted from outside the class<br />

int a = uk.population;<br />

string s = uk.Name;<br />

long b = uk.Gdp; uk.Population = 58000000;<br />

Agilent .NET Course: Module 10,page 7


uk.Gdp = 1000000000;<br />

int c = uk.Region;<br />

10.6 Creating an event<br />

10.6.1 Why would we want <strong>to</strong> create an event<br />

We use events in the user interface. The details are normally hidden – but the code<br />

<strong>to</strong> our methods <strong>to</strong> the interface components is there:<br />

private System.Windows.Forms.But<strong>to</strong>n SortPop;<br />

. . .<br />

#region Windows Form Designer generated code<br />

this.SortPop.Text = "Sort By Population";<br />

this.SortPop.Click += new System.EventHandler(this.SortPop_Click);<br />

. . .<br />

private void SortPop_Click(object sender, System.EventArgs e)<br />

Aside from the standard user interface components that do the hard work for us it is<br />

a relatively unusual requirement <strong>to</strong> implement our own events. We might want <strong>to</strong><br />

create our own events if we want <strong>to</strong> be notified of some occurrence – but we do not<br />

know what that might cause that.<br />

We certainly want <strong>to</strong> create events if we want <strong>to</strong> implement our own components.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

10.6.2 What is involved in creating an event<br />

We require the following<br />

• An action <strong>to</strong> perform when the event is triggered (other people may create<br />

other actions of the same type).<br />

• A handler delegate – this restricts the signature of the actions that may subscribe.<br />

• An event that holds a list of all subscribed actions.<br />

The tasks that are required:<br />

• In the publishing class we declare the delegate.<br />

• In the publishing class we declare the event.<br />

• In the publishing class we insert code <strong>to</strong> trigger the event under some circum‐<br />

Agilent .NET Course: Module 10,page 8


stance.<br />

• In the subscribing class we create a method that matches the delegate.<br />

• In the subscribing class we subscribe <strong>to</strong> the event.<br />

10.7 Megalomania2<br />

10.7.1 How <strong>to</strong> subscribe<br />

We require the detail section <strong>to</strong> be updated au<strong>to</strong>matically whenever a change is<br />

made <strong>to</strong> the country that is currently on display.<br />

We have a method ShowDetailsOfCountry that updates this display:<br />

private void ShowDetailsOfCountry(Object oCountry, EventArgs e)<br />

{<br />

Country c = oCountry as Country;<br />

if (c!=null)<br />

{<br />

detailName.Text =c.Name;<br />

detailRegion.Text =c.Region;<br />

detailPopulation.Text = c.Population.ToString();<br />

}<br />

}<br />

This takes in country and updates the three text boxes <strong>to</strong> reflect that country.<br />

We call this routine whenever the user clicks on the list box.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

We want this routine <strong>to</strong> be called whenever the currently selected country is<br />

changed. We want <strong>to</strong> be sure that it is not possible for the country <strong>to</strong> be changed<br />

without this routine being fired.<br />

Every time the user click on the list box we subscribe <strong>to</strong> the selected country’s On‐<br />

Change event. This ensures that if the country gets changed the display will be<br />

updated. Before we subscribe however we must un‐subscribe the previously selected<br />

country.<br />

Agilent .NET Course: Module 10,page 9


We keep a record of the country that is currently on display<br />

//We do this so that we can "unsubscribe" it when the user<br />

//selects a different item<br />

Country CurrentlyFocussed = null;<br />

Country.changeHandler CurrentlyFocussedCH = null;<br />

//This is the action that causes the subject of the detail panel<br />

//<strong>to</strong> change<br />

private void worldLB_SelectedIndexChanged(object sender, System.EventArgs<br />

e)<br />

{<br />

//Put details of the currently selected country<br />

//in the detail text boxes<br />

Country c =<br />

world[worldLB.SelectedIndex] as Country;<br />

ShowDetailsOfCountry(c,e);<br />

//Now we want <strong>to</strong> subscribe <strong>to</strong> the OnChange event for this<br />

//country.<br />

//First we must unsubscribe whoever was registered before<br />

if (CurrentlyFocussed!=null)<br />

CurrentlyFocussed.OnChange -= CurrentlyFocussedCH;<br />

//We create a new handler<br />

CurrentlyFocussedCH = new<br />

cia.Country.changeHandler(ShowDetailsOfCountry);<br />

//We subscribe our new handler <strong>to</strong> the OnChange event of c<br />

c.OnChange += CurrentlyFocussedCH;<br />

//Remember the currently focussed item so we can unsubscribe<br />

CurrentlyFocussed = c;<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

}<br />

//Show the user which record we are on<br />

label6.Text = String.Format("{0}/{1}",<br />

worldLB.SelectedIndex.ToString(),<br />

worldLB.Items.Count);<br />

Agilent .NET Course: Module 10,page<br />

10


10.7.2 How <strong>to</strong> publish<br />

The class Country is the publisher.<br />

public delegate void changeHandler<br />

(object country, System.EventArgs e);<br />

public event changeHandler OnChange;<br />

public int Population<br />

{<br />

get{return this.population;}<br />

<strong>set</strong><br />

{<br />

this.population=value;<br />

if (OnChange!=null)<br />

OnChange(this,null);<br />

}<br />

}<br />

10.8 Benefits of using events<br />

We have created an application in which the user interface is able <strong>to</strong> respond <strong>to</strong><br />

changes in the data.<br />

Crucially the Country class has no connection with the user interface – even though<br />

the trigger action takes place inside the Country class we do not have <strong>to</strong> recompile<br />

the Country class <strong>to</strong> take account of changes <strong>to</strong> the user interface.<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

Our interface will respond <strong>to</strong> changes even if third parties. Some other user who has<br />

no interest in our interface may make changes. We are moni<strong>to</strong>ring the objects “invisibly”.<br />

Agilent .NET Course: Module 10,page<br />

11


10.9 Tu<strong>to</strong>rial<br />

duction <strong>to</strong> .NET<br />

<strong>Intro</strong><br />

1. In Megalomania2.cs implement the “Sort By Population” but<strong>to</strong>n.<br />

a. Find the PopComparer.Compare method.<br />

b. Remove the exception that is currently thrown.<br />

c. Implement a comparison based on the population. You will need <strong>to</strong>:<br />

i. Cast both objects x and y as Country<br />

ii. Use the Population property (note that the member population<br />

with lower case has been hidden now and Population exposed<br />

as read only).<br />

iii. Population is an int – this supports a CompareTo method – it<br />

works just like the one we used with strings.<br />

2. <strong>Complete</strong> the but<strong>to</strong>n “Show UK region”. Note that we now have <strong>to</strong> use<br />

uk.Region and that uk.region is unavailable.<br />

3. <strong>Complete</strong> the but<strong>to</strong>n “Change UK region” – you may move the UK <strong>to</strong> Africa.<br />

Initially the Region property is read only. You will have <strong>to</strong> change this in<br />

Country.cs<br />

a. Use the <strong>set</strong> statement for Population as an example.<br />

b. If you include all three of the lines then the Region should au<strong>to</strong>matically<br />

be updated.<br />

c. If you do not include the OnChange lines then the event will not get<br />

triggered.<br />

4. Page 630 includes an example of how <strong>to</strong> Serialize an object. We can use this<br />

technique <strong>to</strong> make the world persistent.<br />

a. In the Closing event of the form we can add code <strong>to</strong> write world <strong>to</strong> a<br />

file.<br />

i. Use the object browser <strong>to</strong> find details of the BinaryFormatter<br />

ii. Use the object browser <strong>to</strong> find details of the FileStream<br />

b. Currently the OnLoad event of the form reads world in from a text<br />

file. This can be changed so that it DeSerializes instead.<br />

Agilent .NET Course: Module 10,page<br />

12

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!