Complete set: Intro to C - Bill Buchanan
Complete set: Intro to C - Bill Buchanan
Complete set: Intro to C - Bill Buchanan
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