[go: up one dir, main page]

0% found this document useful (0 votes)
5 views215 pages

c# Programming & .Net Frame Work

The document is a course outline for a Master of Computer Science program at Annamalai University, focusing on C# Programming and the .NET Framework. It includes detailed content on various topics such as .NET architecture, C# fundamentals, and advanced C# features, structured into five units. Each unit contains objectives, summaries, revision points, and assignments to facilitate learning.

Uploaded by

Rathi Sri
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views215 pages

c# Programming & .Net Frame Work

The document is a course outline for a Master of Computer Science program at Annamalai University, focusing on C# Programming and the .NET Framework. It includes detailed content on various topics such as .NET architecture, C# fundamentals, and advanced C# features, structured into five units. Each unit contains objectives, summaries, revision points, and assignments to facilitate learning.

Uploaded by

Rathi Sri
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 215

DMSCSE31

ANNAMALAI UNIVERSITY
DIRECTORATE OF DISTANCE EDUCATION

MASTER OF COMPUTER SCIENCE


THIRD SEMESTER

C# PROGRAMMING & .NET FRAME WORK


ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY

Copyright Reserved
(For Private Circulation Only)
C# Programming and .Net Framework
Table of Content

Unit – I Page no

1.0 Introduction 1
1.1 Objective 1
1.2 Contents 1
1.2.1 About .NET Platform 1
1.2.2 .NET Architecture 3
1.2.3 The Relationship of C# to .NET 3
1.2.4 The Common Language Runtime 4
1.2.5 A Closer Look at Intermediate Language 7
1.2.6 Distinct Value and Reference Types 9
1.2.7 Common Type System 11
1.2.8 Common Language Specification 12
1.2.9 Garbage collection 13
1.2.10 Security 14
1.2.11 Application domains 14
1.2.12 Error Handling with Exceptions 16
1.2.13 Assemblies 18
1.2.14 Reflection 20
1.2.15 .NET Framework Classes 20
1.2.16 Namespaces 21
1.2.17 Creating .NET Applications Using C# 22
1.2.18 The Role of C# in the .NET Enterprise Architecture 25
1.2.19 COM+ 27
1.2.20 The Base Classes 28
1.2.21 CLR Debugger 28
1.3 Revision points 30
1.4 Intext Questions 31
1.5 Summary 31
1.6 Terminal Exercises 32
1.7 Supplementary Materials 32

ANNAMALAI
ANNAMALAI UNIVERSITY
1.8 Assignments
UNIVERSITY
1.9 Reference Books
32
32
1.10 Learning Activities 32
1.11 Keywords 33

Unit – II

2.0 Introduction 34
2.1 Objective 34
2.2 Contents 34
2.2.1 C# Fundamentals 34
2.2.2 The Development of C# 34
2.2.3 The First Compliers 35
2.2.4 The C Programming Language 36
2.2.5 Enter VB 37
2.2.6 Java 38
2.2.7 C# Compared to Other Languages 40
2.2.8 Data Types 44
2.2.9 Program Control Flow 46
2.2.10 Enforcing Rules in C# 49
2.2.11The switch Statement 51
2.2.12 Combining Case Labels 53
2.2.13 Iteration Statements 55
2.2.14 Branching with Jump Statements 62
2.2.15 Reflection 71
2.2.16 Console applications 71
2.2.17 Visual Studio.NET 73
2.2.18 Classes and Objects 76
2.2.19 Arguments In methods 78
2.3 Revision points 80
2.4 Intext Question 81
2.5 Summary 81
2.6 Terminal exercises 82
2.7 Supplementary Materials 82
2.8 Assignments 82
2.9 Reference Books 82
2.10 Learning Activities 82
2.11 Key words 82

Unit – III

3.0 Introduction 83
3.1 Objectives 83
3.2 Contents 83
3.2.1 Important Features 83
3.2.2 Features of Visual Studio 95
3.2.3 Edit and Continue 96
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
3.2.4 ClickOnce
3.2.5 SmartTags
96
97
3.2.6 Code Snippets 98
3.2.7 Exporting IDE Settings 99
3.2.8 Line Revision Marks 99
3.2.9 Temporary Projects 100
3.3 Revision points 100
3.4 Intext Question 101
3.5 Summary 101
3.6 Terminal exercises 102
3.7 Supplementary Materials 102
3.8 Assignments 102
3.9 Reference Books 102
3.10 Learning Activities 102
3.11 Key word 102

Unit – IV

4.0 Introduction 103


4.1 Objectives 103
4.2 Contents 103
4.2.1 Methods 103
4.2.2 Method Structure 103
4.2.3 Namespaces 110
4.2.4 Structs 115
4.2.5 Introduction to Exception Handling 117
4.2.6 Enums Defined 121
4.2.7 Introduction to Classes 129
4.2.8 Inheritance 132
4.2.9 Multiple Interfaces 134
4.2.10 Sealed Classes 135
4.2.11 Polymorphism 136
4.2.12 Operator Overloading 140
4.2.13 Overloadable Operators 143
4.2.14 Properties 144
4.2.15 Indexers 149
4.2.16 Introduction to Delegates and Events 153
4.2.17 Events 157
4.2.18 Operator overloading 160
4.2.19 Interfaces 161
4.3 Revision points 168
4.4 Intext Question 168
4.5 Summary 169
4.6 Terminal exercises 170
4.7 Supplementary Materials 170
4.8 Assignments 170
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
4.9 Reference Books
4.10 Learning Activities
170
170
4.11 Key words 170

Unit – V

5.0 Introduction 171


5.1 Objective 171
5.2 Contents 171
5.2.1 Advance C# 171
5.2.2 Dataset Namespace 172
5.2.3 Preprocessor 177
5.2.4 Unsafe code 182
5.2.5 WINCV Tool – Windows Forms Class Viewer 187
5.2.6 Date and Time 188
5.2.7 Mathematical functions 189
5.2.8 Writing application with C# 191
5.2.9 Creating a Windows Forms application 192
5.2.10 Data access with ADO.NET 197
5.2.11 Classes Derived from System.IO.Stream 199
5.2.12 Enumerators 200
5.2.13 Accessing Data with ADO.NET 201
5.2.14 Components of ADO.NET 206
5.3 Revision points 208
5.4 Intext Question 208
5.5 Summary 209
5.6 Terminal exercises 209
5.7 Supplementary Materials 210
5.8 Assignments 210
5.9 Reference Books 210
5.10 Learning Activities 210
5.11 Key words 210

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
C# Programming And .Net Framework

UNIT - I

1.0 Introduction

The New C# language was created by Microsoft to provide a simple, safe, modern, object
oriented, internet-centric, high performance and robust language for .NET development
C# addresses the problems that exist in many other languages like security,
interoperability, and garbage collection with other languages and cross platform
compatibility. C# inherits the features from its predecessors, C++, Java and VB. If you
are familiar in any one of the above languages, you will appreciate that C# is more
powerful in terms of object orientation, security and simplicity.

C# was developed by a team led by two distinguish Microsoft wizards Anders Heilsbey
and Scott. They were involved in creating Turbo Pascal and leading a team that designed
Borland Delphi an IDE for client server. C# supports structured, object oriented
programming with around 80 keywords and 12 datatypes. C# adopts keyword for
declarations of new classes and their methods.

1.1 Objective

The main objective of this lesson is to know about the overview of the .Net Framework,
Microsoft .Net’s features, about common language runtime and its uses, common
language specification’s features, .Net base classes, and CLR debugger.

1.2 Contents

1.2.1 About .NET Platform

The .NET platform is a new development framework that provides application-


programming interface (API) to the services and API’s of classic windows family
operating systems, There are two specific advantages with .NET. They are the library and
environment. The .NET library is very extensible as windows Apathies can be called
upon for all similar features that is found in windows Operating systems. This library is
known as .NET base classes based on objects and each object implements a number of
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
methods. Microsoft .NET is one of the latest and new technologies introduced by
Microsoft Corporation. Nowadays we use to connect to the internet using a computer and
remote computer responses via a web page and a collection of web pages are called as
websites. The concept in .NET is that these websites can integrate with other sites and
services using standard protocols like HTTP.

All the .NET languages (like C#, VB.NET, and VC++. NET etc) have the .NET
Framework class libraries built into them. The .NET class libraries also supports file I/O,
database operations, XML (Extensible Markup Language) and SOAP (Simple Object
Access Protocol). For example you can develop XML Pages by using C# language.
When someone talks about .NET development, then you should understand that they are

Page 1
C# Programming And .Net Framework

talking about .NET Framework. It includes a runtime environment and a set of class
libraries which is being used by a new language called C-SHARP abbreviated as C#
(more or less similar to C/C++/Java family of languages) and all other .NET Languages.
Simply

Visual Basic C++ C# ..,

Common Language Specification

Web Services User Interface


Visual Studio .Net

Data and XML

Base Class Library

Common Language Runtime

speaking C# is a new language for developing custom solutions for Microsoft's .NET
Platform.

The runtime which we discussed just now is also used by VisualStudio.NET. Visual
Studio.NET provides us with a visual environment to design and develop .NET
Applications. Every language in VisualStudio.NET uses this runtime to execute its
applications. Moreover these languages compile its source code into an intermediate
language. Hence you can very well use a module written using C# in a Visual Basic
Application. For example you can design a user interface with Visual Basic.NET and
write a DLL function using C#. The environment in which the program executes is called
the CLR, Common Language Runtime.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
To impart more clarity, .NET is not an operating system on its own. The operating system
will be windows (till another OS is Made compatible) and the .NET gets imported to the
operating system and the windows API still runs at the base of the screen. The .NET
runtime is layered between windows OS and other applications providing the framework
for developing and running code. Salient feature of .NET can be overlooked to use the
windows API using C# code. This is a major advantage of using C# as other applications
which are not .NET comparable.

Page 2
C# Programming And .Net Framework

1.2.2 .NET Architecture

The C# language cannot be viewed in isolation, but must be considered in parallel with
the .NET Framework. The C# compiler specifically targets .NET, which means that all
code written in C# will always run within the .NET Framework.

This has two important consequences for the C# language:

 The architecture and methodologies of C# reflect the underlying methodologies of


.NET.

 In many cases, specific language features of C# actually depend upon features of


.NET,or of the .NET base classes. Because of this dependence, it is important to
gain some understanding of the architecture and methodology of .NET before we
begin C# programming.

We will begin by going over what happens when all code (including C#) that targets
.NET is compiled and run. Once we have this broad overview, we will take a more
detailed look at the Microsoft Intermediate Language (MSIL or simply IL), the assembly
language which all compiled code ends up in on .NET. In particular, we will see how IL,
in partnership with the Common Type System (CTS) and Common Language
Specification (CLS) works to give us interoperability between languages that target
.NET. We’ll also discuss where common languages (including Visual Basic
and C++) fit into .NET.

Once we’ve done that, we will move on to examine some of the other features of .NET,
including assemblies, namespaces, and the .NET base classes. We’ll finish the chapter
with a brief look at the kinds of applications we can create as C# developers.

1.2.3 The Relationship of C# to .NET

C# is a relatively new programming language, and is significant in two respects:

 It is specifically designed and targeted for use with Microsoft’s .NET Framework

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
(a feature-rich platform for the development, deployment, and execution of
distributed applications).

 It is a language based on the modern object-oriented design methodology, and


when designing it Microsoft has been able to learn from the experience of all the
other similar languages that have been around since object-oriented principles
came to prominence some 20 years ago.

One important thing to make clear is that C# is a language in its own right. Although it is
designed to generate code that targets the .NET environment, it is not itself part of .NET.
There are some features that are supported by .NET but not by C#, and you might be

Page 3
C# Programming And .Net Framework

surprised to learn that there are actually features of the C# language that are not
supported by .NET

However, since the C# language is intended for use with .NET, it is important for us to
have an understanding of this Framework if we want to develop applications in C#
effectively.

1.2.4 The Common Language Runtime

Central to the .NET Framework is its runtime execution environment, known as the
Common Language Runtime (CLR) or the .NET runtime. Code running under the control
of the CLR is often termed managed code.

However, before it can be executed by the CLR, any source code that we develop (in C#
or some other language) needs to be compiled. Compilation occurs in two steps in .NET:
1. Compilation of source code to IL
2. Compilation of IL to platform-specific code by the CLR

This two-stage compilation process is very important, because the existence of the IL
(managed code) is the key to providing many of the benefits of .NET. Let’s see why.

Advantages of Managed Code

Microsoft intermediate language shares with Java byte code the idea that it is a low-level
language with a simple syntax (based on numeric codes rather than text), which can be
very quickly translated into native machine code. Having this well-defined universal
syntax for code has significant advantages.

Platform independence

First, it means that the same file containing byte code instructions can be placed on any
platform; at runtime the final stage of compilation can then be easily accomplished so
that the code will run on that particular platform. In other words, by compiling to IL we
obtain platform independence for .NET, in much the same way as compiling to Java byte
code gives Java platform independence.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Performance improvement

Although we previously made comparisons with Java, IL is actually a bit more ambitious
than Java byte code. IL is always Just-In-Time compiled (known as JIT compilation),
whereas Java byte code was often interpreted. One of the disadvantages of Java was that,
on execution, the process of translating from Java byte code to native executable resulted
in a loss of performance (with the exception of more recent cases, where Java is JIT
compiled on certain platforms).

Page 4
C# Programming And .Net Framework

Instead of compiling the entire application in one go (which could lead to a slow start-up
time), the JIT compiler simply compiles each portion of code as it is called (just-in-time).
When code has been compiled once, the resultant native executable is stored until the
application exits, so that it does not need to be recompiled the next time that portion of
code is run. Microsoft argues that this process is more efficient than compiling the entire
application code at the start, because of the likelihood that large portions of any
application code will not actually be executed in any given run. Using the JIT compiler,
such code will never be compiled.

This explains why we can expect that execution of managed IL code will be almost as
fast as executing native machine code. What it doesn’t explain is why Microsoft expects
that we will get a performance improvement. The reason given for this is that, since the
final stage of compilation takes place at runtime, the JIT compiler will know exactly what
processor type the program will run on. This means that it can optimize the final
executable code to take advantage of any features or particular machine code instructions
offered by that particular processor.

Traditional compilers will optimize the code, but they can only perform optimizations
that are independent of the particular processor that the code will run on. This is because
traditional compilers compile to native executable before the software is shipped. This
means that the compiler doesn’t know what type of processor the code will run on
beyond basic generalities, such as that it will be an x86-compatible processor or an Alpha
processor. Visual Studio 6, for example, optimizes for a generic Pentium machine, so the
code that it generates cannot take advantage of hardware features of Pentium III
processors. On the other hand, the JIT compiler can do all the optimizations that Visual
Studio 6 can, and in addition it will optimize for the particular processor the code is
running on.

Language interoperability

The use of IL not only enables platform independence; it also facilitates language
interoperability. Simply put, you can compile to IL from one language, and this compiled
code should then be interoperable with code that has been compiled to IL from another
language. You’re probably now wondering which languages aside from C# are
interoperable with .NET, so let’s briefly discuss how some of the other common
languages fit into .NET.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Visual Basic .NET

Visual Basic .NET has undergone a complete revamp from Visual Basic 6 to bring it up-
to-date with .NET. The way that Visual Basic has evolved over the last few years means
that in its previous version, Visual Basic 6, it was not a suitable language for running
.NET programs. For example, it is heavily integrated into COM and works by exposing
only event handlers as source code to the developer—most of the background code is not
available as source code. Not only that, it does not support implementation inheritance,

Page 5
C# Programming And .Net Framework

and the standard data types Visual Basic 6 uses are incompatible with .NET. Visual Basic
6 was upgraded to Visual Basic .NET, and the changes that were made to the language
are so extensive you might as well regard Visual Basic .NET as a new language. Existing
Visual Basic 6 code does not compile as Visual Basic .NET code. Converting a Visual
Basic 6 program to Visual Basic .NET requires extensive changes to the code. However,
Visual Studio .NET (the upgrade of VS for use with .NET) can do most of the changes
for you. If you attempt to read a Visual Basic 6 project into Visual Studio .NET, it will
upgrade the project for you, which means that it will rewrite the Visual Basic 6 source
code into Visual Basic .NET source code. Although this means that the work involved for
you is heavily cut down, you will need to check through the new Visual Basic .NET code
to make sure that the project still works as intended because the conversion might not be
perfect.

One side effect of this language upgrade is that it is no longer possible to compile Visual
Basic .NET to native executable code. Visual Basic .NET compiles only to IL, just as C#
does. If you need to continue coding in Visual Basic 6, you may do so, but the executable
code produced will completely ignore the .NET Framework, and you’ll need to keep
Visual Studio 6 installed if you want to continue to work in this developer environment.

Visual C++ .NET

Visual C++ 6 already had a large number of Microsoft-specific extensions on Windows.


With Visual C++ .NET, extensions have been added to support the .NET Framework.
This means that existing C++ source code will continue to compile to native executable
code without modification. It also means, however, that it will run independently of the
.NET runtime. If you want your C++ code to run within the .NET Framework, then you
can simply add the following line to the beginning of your code:

#using <mscorlib.dll>

You can also pass the flag /clr to the compiler, which then assumes that you want to
compile to managed code, and will hence emit IL instead of native machine code. The
interesting thing about C++ is that when you compile to managed code, the compiler can
emit IL that contains an embedded native executable. This means that you can mix
managed types and unmanaged types in your C++ code. Thus the managed C++ code:

ANNAMALAI
ANNAMALAI UNIVERSITY
class MyClass
{
UNIVERSITY
defines a plain C++ class, whereas the code:
__gc class MyClass
{

will give you a managed class, just as if you’d written the class in C# or Visual Basic
.NET. The advantage of using managed C++ over C# code is that we can call unmanaged
C++ classes from managed C++ code without having to resort to COM interop.

Page 6
C# Programming And .Net Framework

The compiler raises an error if you attempt to use features that are not supported by .NET
on managed types (for example, templates or multiple inheritance of classes). You will
also find that you will need to use nonstandard C++ features (such as the __gc keyword
shown in the previous code) when using managed classes.

Because of the freedom that C++ allows in terms of low-level pointer manipulation and
so on, the C++ compiler is not able to generate code that will pass the CLR’s memory
type safety tests.

Visual J# .NET

The latest language to be added to the mix is Visual J# .NET. Prior to .NET Framework
1.1, users were able to use J# only after making a separate download. Now the J#
language is built into the .NET Framework. Because of this, J# users are able to take
advantage of all the usual features of Visual Studio .NET. Microsoft expects that most
J++ users will find it easiest to use J# if they want to work with .NET. Instead of being
targeted at the Java runtime libraries, J# uses the same base class libraries that the rest
of the .NET compliant languages use. This means that you can use J# for building
ASP.NET Web applications, Windows Forms, XMLWeb services, and everything else
that is possible—just as C# and Visual Basic .NET can.

Scripting languages

Scripting languages are still around, although, in general, their importance is likely to
decline with the advent of .NET. JScript, on the other hand, has been upgraded to JScript
.NET. We can now write ASP.NET pages in JScript .NET, run JScript .NET as a
compiled rather than an interpreted language, and write strongly typed JScript .NET
code. With ASP.NET there is no reason to use scripting languages in serverside Web
pages. VBA is, however, still used as a language for Microsoft Office and Visual Studio
macros.

COM and COM+

Technically speaking, COM and COM+ aren’t technologies targeted at .NET, because
components based on them cannot be compiled into IL (although it’s possible to do so to
some degree using managed C++, if the original COM component was written in C++).
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
However, COM+ remains an important tool, because its features are not duplicated in
.NET. Also, COM components will still work—and .NET incorporates COM
interoperability features that make it possible for managed code to call up COM
components and vice versa.

1.2.5 A Closer Look at Intermediate Language

Microsoft intermediate language obviously plays a fundamental role in the .NET


Framework. As C# developers, we now understand that our C# code will be compiled
into IL before it is executed (indeed, the C# compiler only compiles to managed code). It

Page 7
C# Programming And .Net Framework

makes sense, then, that we should now take a closer look at the main characteristics of IL,
since any language that targets .NET would logically need to support the main
characteristics of IL too.

Here are the important features of IL:


. Object-orientation and use of interfaces
. Strong distinction between value and reference types
. Strong data typing
. Error handling through the use of exceptions
. Use of attributes

A closer look at each of these characteristics.

Support for Object Orientation and Interfaces

The language independence of .NET does have some practical limitations. IL is


inevitably going to implement some particular programming methodology, which means
that languages targeting it are going to have to be compatible with that methodology. The
particular route that Microsoft has chosen to follow for IL is that of classic object-
oriented programming, with single implementation inheritance of classes.

Besides classic object-oriented programming, IL also brings in the idea of interfaces,


which saw their first implementation under Windows with COM..NET interfaces are not
the same as COM interfaces; they do not need to support any of the COM infrastructure
(for example, they are not derived from IUnknown, and they do not have associated
GUIDs). However, they do share with COM interfaces the idea that they provide a
contract, and classes that implement a given interface must provide implementations of
the methods and properties specified by that interface.

Object orientation and language interoperability

We have now seen that working with .NET means compiling to IL, and that in turn
means that you will need to use traditional object-oriented methodologies. However, that
alone is not sufficient to give us language interoperability. After all, C++ and Java both
use the same object-oriented paradigms, but they are still not regarded as interoperable.
We need to look a little more closely at the concept of language interoperability.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
To start with, we need to consider exactly what we mean by language interoperability.
After all, COM allowed components written in different languages to work together in
the sense of calling each other’s methods. What was inadequate about that? COM, by
virtue of being a binary standard, did allow components to instantiate other components
and call methods or properties against them, without worrying about the language the
respective components were written in. In order to achieve this, however, each object had
to be instantiated through the COM runtime, and accessed through an interface.

Page 8
C# Programming And .Net Framework

Depending on the threading models of the relative components, there may have been
large performance losses associated with marshaling data between apartments or running
components or both on different threads. In the extreme case of components that are
hosted as an executable rather than DLL files, separate processes would need to be
created in order to run them. The emphasis was very much that components could talk
to each other, but only via the COM runtime. In no way with COM did components
written in different languages directly communicate with each other, or instantiate
instances of each other—it was always done with COM as an intermediary. Not only that,
but the COM architecture did not permit implementation inheritance, which meant that it
lost many of the advantages of object-oriented programming.

An associated problem was that, when debugging, you would still have to debug
components written in different languages independently. It was not possible to step
between languages in the debugger.

So what we really mean by language interoperability is that classes written in one


language should be able to talk directly to classes written in another language. In
particular:

. A class written in one language can inherit from a class written in another language.
. The class can contain an instance of another class, no matter what the languages of the
two classes are.
. An object can directly call methods against another object written in another language.
. Objects (or references to objects) can be passed around between methods.
. When calling methods between languages we can step between the method calls in the
debugger, even when this means stepping between source code written in different
languages.

1.2.6 Distinct Value and Reference Types

As with any programming language, IL provides a number of predefined primitive data


types. One characteristic of IL, however, is that it makes a strong distinction between
value and reference types.

Value types are those for which a variable directly stores its data, while reference types
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
are those for which a variable simply stores the address at which the corresponding data
can be found.

In C++ terms, reference types can be considered to be similar to accessing a variable


through a pointer, while for Visual Basic, the best analogy for reference types are objects,
which in Visual Basic 6 are always accessed through references. IL also lays down
specifications about data storage: instances of reference types are always stored in an area
of memory known as the managed heap, while value types are normally stored on the
stack

Page 9
C# Programming And .Net Framework

Strong Data Typing

One very important aspect of IL is that it is based on exceptionally strong data typing.
What we mean by that is that all variables are clearly marked as being of a particular,
specific data type (there is no room in IL, for example, for the Variant data type
recognized by Visual Basic and scripting languages).

In particular, IL does not normally permit any operations that result in ambiguous data
types. For instance, Visual Basic 6 developers are used to being able to pass variables
around without worrying too much about their types, because Visual Basic 6
automatically performs type conversion. C++ developers are used to routinely casting
pointers between different types. Being able to perform this kind of operation can be
great for performance, but it breaks type safety. Hence, it is permitted only under certain
circumstances in some of the languages that compile to managed code. Indeed, pointers
(as opposed to references) are only permitted in marked blocks of code in C#, and not at
all in Visual Basic (although they are allowed in managed C++). Using pointers in your
code causes it to fail the memory type safety checks performed by the CLR.

Some languages compatible with .NET, such as Visual Basic .NET, still allow some
laxity in typing, but that is only possible because the compilers behind the scenes ensure
the type safety is enforced in the emitted IL.

Although enforcing type safety might initially appear to hurt performance, in many cases
the benefits gained from the services provided by .NET that rely on type safety far
outweigh this performance loss.

Such services include:


. Language interoperability
. Garbage collection
. Security
. Application domains

Why strong data typing is particularly important for these features of .NET. The
Importance of strong data typing for language interoperability

If a class is to derive from or contains instances of other classes, it needs to know about
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
all the data types used by the other classes. This is why strong data typing is so important.
Indeed, it is the absence of any agreed system for specifying this information in the past
that has always been the real barrier to inheritance and interoperability across languages.
This kind of information is simply not present in a standard executable file or DLL.

Suppose that one of the methods of a Visual Basic .NET class is defined to return an
Integer—one of the standard data types available in Visual Basic .NET. C# simply does
not have any data type of that name. Clearly, we will only be able to derive from the
class, use this method, and use the return type from C# code, if the compiler knows how
to map Visual Basic .NET’s Integer type to some known type that is defined in C#.

Page 10
C# Programming And .Net Framework

1.2.7 Common Type System

This data type problem is solved in .NET through the use of the Common Type System
(CTS). The CTS defines the predefined data types that are available in IL, so that all
languages that target the .NET Framework will produce compiled code that is ultimately
based on these types. For the example that we were considering before, Visual Basic
.NET’s Integer is actually a 32-bit signed integer, which maps exactly to the IL type
known as Int32.

This will therefore be the data type specified in the IL code. Because the C# compiler is
aware of this type, there is no problem. At source code level, C# refers to Int32 with the
keyword int, so the compiler will simply treat the Visual Basic .NET method as if it
returned an int. The CTS doesn’t merely specify primitive data types, but a rich hierarchy
of types, which includes welldefined points in the hierarchy at which code is permitted to
define its own types. The hierarchical structure of the Common Type System reflects the
single-inheritance object-oriented methodology of IL, and resembles Figure 1.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
The following table explains the types shown in Figure 1.

Type Meaning

Type - Base class that represents any type.


Value Type - Base class that represents any value type.
Reference Types - Any data types that are accessed through a reference and
stored on the heap.
Built-in Value Types - Includes most of the standard primitive types, which
represent numbers, Boolean values, or characters.
Enumerations - Sets of enumerated values.

Page 11
C# Programming And .Net Framework

User-defined Value Types -Types that have been defined in source code and are stored
as value types. In C# terms, this means any struct.
Interface Types - Interfaces.
Pointer Types - Pointers.
Self-describing Types - Data types that provide information about themselves for
the benefit of the garbage collector
Arrays - Any type that contains an array of objects.
Class Types - Types that are self-describing but are not arrays.
Delegates - Types that are designed to hold references to methods.
User-defined Reference Types -Types that have been defined in source code and are
stored as reference types. In C# terms, this means any
class.
Boxed Value Types - A value type that is temporarily wrapped in a reference so
that it can be stored on the heap.

1.2.8 Common Language Specification

The Common Language Specification (CLS) works with the CTS to ensure language
interoperability. The CLS is a set of minimum standards that all compilers targeting .NET
must support. Since IL is a very rich language, writers of most compilers will prefer to
restrict the capabilities of a given compiler to only support a subset of the facilities
offered by IL and the CTS. That is fine, as long as the compiler supports everything that
is defined in the CLS.

For example, let’s look at case sensitivity. IL is case-sensitive. Developers who work
with case-sensitive languages regularly take advantage of the flexibility this case
sensitivity gives them when selecting variable names. Visual Basic .NET, however, is not
case sensitive. The CLS works around this by indicating that CLS-compliant code should
not expose any two names that differ only in their case. Therefore, Visual Basic .NET
code can work with CLS-compliant code.

This example shows that the CLS works in two ways. First, it means that individual
compilers do not have to be powerful enough to support the full features of .NET—this
should encourage the development of compilers for other programming languages that
target .NET. Second, it provides a guarantee that, if you restrict your classes to only
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
exposing CLS-compliant features, then it is guaranteed that code written in any other
compliant language can use your classes.

The beauty of this idea is that the restriction to using CLS-compliant features only applies
to public and protected members of classes and public classes. Within the private
implementations of your classes, you can write whatever non-CLS code you want,
because code in other assemblies (units of managed code, see later in this chapter) cannot
access this part of your code anyway.

Page 12
C# Programming And .Net Framework

In general, the CLS won’t affect your C# code very much, because there are very few
non–CLS-compliant features of C# anyway. It is perfectly acceptable to write non–CLS-
compliant code. However, if you do, the compiled IL code isn’t guaranteed to be fully
language interoperable.

1.2.9 Garbage collection

The garbage collector is .NET’s answer to memory management, and in particular to the
question of what to do about reclaiming memory that running applications ask for. Up
until now there have been two techniques used on the Windows platform for de-
allocating memory that processes have dynamically requested from the system:

. Make the application code do it all manually.


. Make objects maintain reference counts.

Having the application code responsible for de-allocating memory is the technique used
by lower-level, high-performance languages such as C++. It is efficient, and it has the
advantage that (in general) resources are never occupied for longer than unnecessary. The
big disadvantage, however, is the frequency of bugs. Code that requests memory also
should explicitly inform the system when it no longer requires that memory. However, it
is easy to overlook this, resulting in memory leaks.

Although modern developer environments do provide tools to assist in detecting memory


leaks, they remain difficult bugs to track down, because they have no effect until so much
memory has been leaked that Windows refuses to grant any more to the process. By this
point, the entire computer may have appreciably slowed down due to the memory
demands being made on it. Maintaining reference counts is favored in COM. The idea is
that each COM component maintains a count of how many clients are currently
maintaining references to it. When this count falls to zero, the component can destroy
itself and free up associated memory and resources. The problem with this is
that it still relies on the good behavior of clients to notify the component that they have
finished with it.

It only takes one client not to do so, and the object sits in memory. In some ways, this is a
potentially more serious problem than a simple C++-style memory leak, because the
COM object may exist in its own process, which means that it will never be removed by
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
the system (at least with C++ memory leaks, the system can reclaim all memory when the
process terminates). The .NET runtime relies on the garbage collector instead. This is a
program whose purpose is to clean up memory.

The idea is that all dynamically requested memory is allocated on the heap (that is true
for all languages, although in the case of .NET, the CLR maintains its own managed heap
for .NET applications to use). Every so often, when .NET detects that the managed heap
for a given process is becoming full and therefore needs tidying up, it calls the garbage
collector. The garbage collector runs through variables currently in scope in your code,
examining references to objects stored on the heap to identify which ones are accessible

Page 13
C# Programming And .Net Framework

from your code—that is to say which objects have references that refer to them. Any
objects that are not referred to are deemed to be no longer accessible from your code and
can therefore be removed. Java uses a similar system of garbage collection to this.
Garbage collection works in .NET because IL has been designed to facilitate the process.
The principle requires that you cannot get references to existing objects other than by
copying existing references and that IL is type safe. In this context, what we mean is that
if any reference to an object exists, then there is sufficient information in the reference to
exactly determine the type of the object.

It would not be possible to use the garbage collection mechanism with a language such as
unmanaged C++, for example, because C++ allows pointers to be freely cast between
types.

One important aspect of garbage collection is that it is not deterministic. In other words,
you cannot guarantee when the garbage collector will be called; it will be called when the
CLR decides that it is needed (unless you explicitly call the collector). Though it is also
possible to override this process and call up the garbage collector in your code.

1.2.10 Security

.NET can really excel in terms of complementing the security mechanisms provided by
Windows because it can offer code-based security, whereas Windows only really offers
role-based security.

Role-based security is based on the identity of the account under which the process is
running, in other words, who owns and is running the process. Code-based security on
the other hand is based on what the code actually does and on how much the code is
trusted. Thanks to the strong type safety of IL, the CLR is able to inspect code before
running it in order to determine required security permissions. .NET also offers a
mechanism by which code can indicate in advance what security permissions it will
require to run.

The importance of code-based security is that it reduces the risks associated with running
code of dubious origin (such as code that you’ve downloaded from the Internet). For
example, even if code is running under the administrator account, it is possible to use
code-based security to indicate that that code should still not be permitted to perform
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
certain types of operation that the administrator account would normally be allowed to
do, such as read or write to environment variables, read or write to the registry, or to
access the .NET reflection features.

1.2.11 Application domains

Application domains are an important innovation in .NET and are designed to ease the
overhead involved when running applications that need to be isolated from each other,
but which also need to be able to communicate with each other. The classic example of
this is a Web server application, which may be simultaneously responding to a number of

Page 14
C# Programming And .Net Framework

browser requests. It will, therefore, probably have a number of instances of the


component responsible for servicing those requests running simultaneously. In pre-.NET
days, the choice would be between allowing those instances to share a process, with the
resultant risk of a problem in one running instance bringing the whole Web site down, or
isolating those instances in separate processes, with the associated performance overhead.

The only means of isolating code has been through processes. When you start a new
application, it runs within the context of a process. Windows isolates processes from each
other through address spaces. The idea is that each process has available 4GB of virtual
memory in which to store its data and executable code (4GB is for 32-bit systems; 64-bit
systems use more memory). Windows imposes an extra level of indirection by which this
virtual memory maps into a particular area of actual physical memory or disk space. Each
process gets a different mapping, with no overlap between the actual physical memories
that the blocks of virtual address space map to (see Figure 1-2).

In general, any process is only able to access memory by specifying an address in virtual
memory— processes do not have direct access to physical memory. Hence it is simply
impossible for one process to access the memory allocated to another process. This
provides an excellent guarantee that any badly behaved code will not be able to damage
anything outside its own address space. (Note that on Windows 95/98, these safeguards
are not quite as thorough as they are on Windows NT/2000/XP/2003, so the theoretical
possibility exists of applications crashing Windows by writing to inappropriate memory.)

Processes don’t just serve as a way to isolate instances of running code from each other.
On Windows NT/2000/XP/2003 systems, they also form the unit to which security
privileges and permissions are assigned. Each process has its own security token, which
indicates to Windows precisely what operations that process is permitted to do.

While processes are great for security reasons, their big disadvantage is in the area of
performance. Often a number of processes will actually be working together, and
therefore need to communicate with each other. The obvious example of this is where a
process calls up a COM component, which is an executable, and therefore is required to
run in its own process. The same thing happens in COM when surrogates are used. Since
processes cannot share any memory, a complex marshaling process has to be used to
copy data between the processes.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
This results in a very significant performance hit. If you need components to work
together and don’t want that performance hit, then you have to use DLL-based
components and have everything running in the same address space—with the associated
risk that a badly behaved component will bring everything else down.

Application domains are designed as a way of separating components without resulting in


the performance problems associated with passing data between processes. The idea is
that any one process is divided into a number of application domains. Each application
domain roughly corresponds to a single application, and each thread of execution will be
running in a particular application domain If different executables are running in the

Page 15
C# Programming And .Net Framework

same process space, then they are clearly able to easily share data, because theoretically
they can directly see each other’s data. However, although this is possible in principle,
the CLR makes sure that this does not happen in practice by inspecting the code for each
running application, to ensure that the code cannot stray outside its own data areas.

In fact, it is usually possible to do this because of the strong type safety of the IL. In most
cases, unless code is using unsafe features such as pointers, the data types it is using will
ensure that memory is not accessed inappropriately. For example, .NET array types
perform bounds checking to ensure that no outof bounds array operations are permitted.
If a running application does need to communicate or share data with other applications
running in different application domains, then it must do so by calling on .NET’s
remoting services.

Code that has been verified to check that it cannot access data outside its application
domain (other than through the explicit remoting mechanism) is said to be memory type-
safe. Such code can safely be run alongside other type-safe code in different application
domains within the same process.

1.2.12 Error Handling with Exceptions

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
The .NET Framework is designed to facilitate handling of error conditions using the same
mechanism, based on exceptions, that is employed by Java and C++. C++ developers
should note that because of IL’s stronger typing system, there is no performance penalty
associated with the use of exceptions with IL in the way that there is in C++. Briefly, the
idea is that certain areas of code are designated as exception handler routines, with each
one able to deal with a particular error condition (for example, a file not being found, or
being denied permission to perform some operation). These conditions can be defined as
narrowly or as widely as you wish. The exception architecture ensures that when an error
condition occurs, execution can immediately jump to the exception handler routine that is
most specifically geared to handle the exception condition in question.

Page 16
C# Programming And .Net Framework

The architecture of exception handling also provides a convenient means to pass an


object containing precise details of the exception condition to an exception handling
routine. This object might include an appropriate message for the user and details of
exactly where in the code the exception was detected.

Most exception handling architecture, including the control of program flow when an
exception occurs, is handled by the high-level languages (C#, Visual Basic .NET, C++),
and is not supported by any special

IL commands. C#, for example, handles exceptions using try{}, catch{}, and finally{}
blocks of code.

What .NET does do, however, is provide the infrastructure to allow compilers that target
.NET to support exception handling. In particular, it provides a set of .NET classes that
can represent the exceptions, and the language interoperability to allow the thrown
exception objects to be interpreted by the exception handling code, irrespective of what
language the exception handling code is written in. This language independence is absent
from both the C++ and Java implementations of exception handling, although it is present
to a limited extent in the COM mechanism for handling errors, which involves returning
error codes from methods and passing error objects around. The fact that exceptions are
handled consistently in different languages is a crucial aspect of facilitating multi-
language development.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Use of Attributes

Attributes are a feature that is familiar to developers who use C++ to write COM
components (through their use in Microsoft’s COM Interface Definition Language
[IDL]). The initial idea of an attribute was that it provided extra information concerning
some item in the program that could be used by the compiler.

Attributes are supported in .NET—and hence now by C++, C#, and Visual Basic .NET.
What is, however, particularly innovative about attributes in .NET is that a mechanism
exists whereby you can define your own custom attributes in your source code. These

Page 17
C# Programming And .Net Framework

user-defined attributes will be placed with the metadata for the corresponding data types
or methods. This can be useful for documentation purposes, where they can be used in
conjunction with reflection technology in order to perform programming tasks based
on attributes. Also, in common with the .NET philosophy of language independence,
attributes can be defined in source code in one language, and read by code that is written
in another language.

1.2.13 Assemblies

An assembly is the logical unit that contains compiled code targeted at the .NET
Framework. An assembly is completely self-describing, and is a logical rather than a
physical unit, which means that it can be stored across more than one file (indeed
dynamic assemblies are stored in memory, not on file at all). If an assembly is stored in
more than one file, then there will be one main file that contains the entry point and
describes the other files in the assembly. Note that the same assembly structure is used
for both executable code and library code. The only real difference is that an executable
assembly contains a main program entry point, whereas a library assembly doesn’t.
An important characteristic of assemblies is that they contain metadata that describes the
types and methods defined in the corresponding code. An assembly, however, also
contains assembly metadata that describes the assembly itself. This assembly metadata,
contained in an area known as the manifest, allows checks to be made on the version of
the assembly, and on its integrity.

The fact that an assembly contains program metadata means that applications or other
assemblies that call up code in a given assembly do not need to refer to the registry, or to
any other data source, in order to find out how to use that assembly. This is a significant
break from the old COM way of doing things, in which the GUIDs of the components
and interfaces had to be obtained from the registry, and in some cases, the details of the
methods and properties exposed would need to be read from a type library.

Having data spread out in up to three different locations meant there was the obvious risk
of something getting out of synchronization, which would prevent other software from
being able to use the component successfully. With assemblies, there is no risk of this
happening, because all the metadata is stored with the program executable instructions.
Note that even though assemblies are stored across several files, there are still no
problems with data going out of synchronization. This is because the file that contains
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
the assembly entry point also stores details of, and a hash of, the contents of the other
files, which means that if one of the files gets replaced, or in any way tampered with, this
will almost certainly be detected and the assembly will refuse to load.
Assemblies come in two types: shared and private assemblies.

Private Assemblies

Private assemblies are the simplest type. They normally ship with software and are
intended to be used only with that software. The usual scenario in which you will ship
private assemblies is when you are supplying an application in the form of an executable

Page 18
C# Programming And .Net Framework

and a number of libraries, where the libraries contain code that should only be used with
that application. The system guarantees that private assemblies will not be used by other
software, because an application may only load private assemblies that are located in the
same folder that the main executable is loaded in, or in a subfolder of it.

Because we would normally expect that commercial software would always be installed
in its own directory, this means that there is no risk of one software package overwriting,
modifying, or accidentally loading private assemblies intended for another package. As
private assemblies can only be used by the software package that they are intended for,
this means that you have much more control over what software uses them.

There is, therefore, less need to take security precautions, since there is no risk, for
example, of some other commercial software overwriting one of your assemblies with
some new version of it (apart from the case where software is designed specifically to
perform malicious damage). There are also no problems with name collisions. If classes
in your private assembly happen to have the same name as classes in someone else’s
private assembly that doesn’t matter, because any given application will only be able to
see the one set of private assemblies. Because a private assembly is entirely self-
contained, the process of deploying it is simple. You simply place the appropriate file(s)
in the appropriate folder in the file system (there are no registry entries that need to be
made). This process is known as zero impact (xcopy) installation.

Shared Assemblies

Shared assemblies are intended to be common libraries that any other application can use.
Because any other software can access a shared assembly, more precautions need to be
taken against the following risks:

1. Name collisions, where another company’s shared assembly implements types


that have the same names as those in your shared assembly. Because client code
can theoretically have access to both assemblies simultaneously, this could be a
serious problem.
2. The risk of an assembly being overwritten by a different version of the same
assembly—the new version being incompatible with some existing client code.

The solution to these problems involves placing shared assemblies in a special directory
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
subtree in the file system, known as the global assembly cache (GAC). Unlike with
private assemblies, this cannot be done by simply copying the assembly into the
appropriate folder—it needs to be specifically installed into the cache. This process can
be performed by a number of .NET utilities and involves carrying out certain checks on
the assembly, as well as setting up a small folder hierarchy within the assembly cache
that is used to ensure assembly integrity.

In order to avoid the risk of name collisions, shared assemblies are given a name that is
based on private key cryptography (private assemblies are simply given the same name as

Page 19
C# Programming And .Net Framework

their main file name). This name is known as a strong name, is guaranteed to be unique,
and must be quoted by applications that reference a shared assembly.

Problems associated with the risk of overwriting an assembly are addressed by specifying
version information in the assembly manifest, and by allowing side-by-side installations.

1.2.14 Reflection

Since assemblies store metadata, including details of all the types and members of these
types that are defined in the assembly, it is possible to access this metadata
programmatically. Full details of this can be found in Chapter 10. This technique, known
as reflection, raises interesting possibilities, since it means that managed code can
actually examine other managed code, or can even examine itself, to determine
information about that code. This is most commonly used to obtain the details of
attributes, although you can also use reflection, among other purposes, as an indirect way
of instantiating classes or calling methods, given the names of those classes on methods
as strings. In this way you could select classes to instantiate methods to call at runtime,
rather than compile time, based on user input (dynamic binding).

1.2.15 .NET Framework Classes

Perhaps one of the biggest benefits of writing managed code, at least from a developer’s
point of view, is that you get to use the .NET base class library.

The .NET base classes are a massive collection of managed code classes that allow you to
do almost any of the tasks that were previously available through the Windows API.
These classes follow the same object model IL uses, based on single inheritance. This
means that you can either instantiate objects of whichever .NET base class is appropriate,
or you can derive your own classes from them.

The great thing about the .NET base classes is that they have been designed to be very
intuitive and easy to use. For example, to start a thread, you call the Start() method of the
Thread class. To disable a TextBox, you set the Enabled property of a TextBox object to
false. This approach—while familiar to Visual Basic and Java developers, whose
respective libraries are just as easy to use—will be a welcome relief to C++ developers,
who for years have had to cope with such API functions as GetDIBits(),
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
RegisterWndClassEx(), and IsEqualIID(), as well as a whole plethora of functions that
required Windows handles to be passed around.

On the other hand, C++ developers always had easy access to the entire Windows API,
whereas Visual Basic 6 and Java developers were more restricted in terms of the basic
operating system functionality that they have access to from their respective languages.
What is new about the .NET base classes is that they combine the ease of use that was
typical of the Visual Basic and Java libraries with the relatively comprehensive coverage
of the Windows API functions. There are still many features of Windows that are not
available through the base classes, and for which you will need to call into the API

Page 20
C# Programming And .Net Framework

functions, but in general, these are now confined to the more exotic features. For
everyday use, you will probably find the base classes adequate. And if you do need to call
into an API function, .NET offers a so-called platform-invoke which ensures data types
are correctly converted, so the task is no harder than calling the function directly from
C++ code would have been—regardless of whether you are coding in C#, C++,
or Visual Basic

.NET.WinCV, a Windows-based utility, can be used to browse the classes, structs,


interfaces, and enums in the base class library. That is how comprehensive base classes
are. As a rough guide, the areas covered by the .NET base classes include:
 Core features provided by IL
 Windows GUI support and controls
 Web Forms
 Data Access
 Directory Access
 File system and registry access.
 Networking and Web browsing
 .NET attributes and reflection
 Access to aspects of the Windows OS
 COM interoperability
Incidentally, according to Microsoft sources, a large proportion of the .NET base classes
have actuallybeen written in C#!

1.2.16 Namespaces

Namespaces are the way that .NET avoids name clashes between classes. They are
designed to avoid the situation in which you define a class to represent a customer, name
your class Customer, and then someone else does the same thing (a likely scenario—the
proportion of businesses that have customers seems to be quite high).

A namespace is no more than a grouping of data types, but it has the effect that the names
of all data types within a namespace automatically get prefixed with the name of the
namespace. It is also possible to nest namespaces within each other. For example, most of
the general-purpose .NET base classes are in a namespace called System. The base class
Array is in this namespace, so its full name is System.Array.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
.NET requires all types to be defined in a namespace, so for example you could place
your Customer class in a namespace called YourCompanyName. This class would have
the full name YourCompanyName.Customer. If a namespace is not explicitly supplied,
then the type will be added to a nameless global namespace.

Microsoft recommends that for most purposes you supply at least two nested namespace
names: the first one refers to the name of your company, the second one refers to the
name of the technology or software package that the class is a member of, such as
YourCompanyName.SalesServices.Customer.

Page 21
C# Programming And .Net Framework

This protects, in most situations, the classes in your application from possible name
clashes with classes written by other organizations.

1.2.17 Creating .NET Applications Using C#

C# can also be used to create console applications: text-only applications that run in a
DOS window. You’ll probably use console applications when unit testing class libraries,
and for creating Unix or Linux daemon processes. However, more often you’ll use C# to
create applications that use many of the technologies associated with .NET.

Creating ASP.NET Applications

Active Server Pages (ASP) is a Microsoft technology for creating Web pages with
dynamic content. An ASP page is basically an HTML file with embedded chunks of
server-side VBScript or JavaScript. When a client browser requests an ASP page, the
Web server delivers the HTML portions of the page, processing the server-side scripts as
it comes to them. Often these scripts query a database for data, and mark up that data in
HTML. ASP is an easy way for clients to build browser-based applications.

However, ASP is not without its shortcomings. First, ASP pages sometimes render
slowly because the server-side code is interpreted instead of compiled. Second, ASP files
can be difficult to maintain because they were unstructured; the server-side ASP code and
plain HTML are all jumbled up together. Third, ASP sometimes make development
difficult because there is little support for error handling and type-checking.

Specifically, if you are using VBScript and want to implement error handling in your
pages, you have to use the On Error Resume Next statement, and follow every
component call with a check to Err.Number to make sure that the call had gone well.
ASP.NET is a complete revision of ASP that fixes many of its problems. It does not
replace ASP; rather, ASP.NET pages can live side by side on the same server with legacy
ASP applications.

Features of ASP.NET

First, and perhaps most importantly, ASP.NET pages are structured. That is, each page is
effectively a class that inherits from the .NET System.Web.UI.Page class, and can
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
override a set of methods that are evoked during the Page object’s lifetime. Because you
can factor a page’s functionality into event handlers with explicit meanings, ASP.NET
pages are easier to understand.

Another nice thing about ASP.NET pages is that you can create them in Visual Studio
.NET, the same environment in which you create the business logic and data access
components that those ASP.NET pages use. A Visual Studio .NET project, or solution,
contains all of the files associated with an application. Moreover, you can debug your
classic ASP pages in the editor as well; in the old days of Visual InterDev, it was often a
vexing challenge to configure InterDev and the project’s Web server to turn debugging

Page 22
C# Programming And .Net Framework

on. For maximum clarity, the ASP.NET code-behind feature lets you take the structured
approach even further.

ASP.NET allows you to isolate the server-side functionality of a page to a class, compile
that class into a DLL, and place that DLL into a directory below the HTML portion. A
code-behind directive at the top of the page associates the file with its DLL. When a
browser requests the page, the Web server fires the events in the class in the page’s code-
behind DLL. Last but not least, ASP.NET is remarkable for its increased performance.
Whereas classic ASP pages are interpreted with each page request, the Web server caches
ASP.NET pages after compilation. This means that subsequent requests of an ASP.NET
page execute more quickly than the first.

ASP.NET also makes it easy to write pages that cause forms to be displayed by the
browser, which you might use in an intranet environment. The traditional wisdom is that
form-based applications offer a richer user interface, but are harder to maintain because
they run on so many different machines. For this reason, people have relied on form-
based applications when rich user interfaces were a necessity and extensive support could
be provided to the users. With the advent of Internet Explorer 5 and the lackluster
performance of Navigator 6, however, the advantages of form-based applications are
clouded. IE 5’s consistent and robust support for DHTML allows the programmer to
create Web-based applications that are every bit as pretty as their fat client equivalents.
Of course, such applications necessitate standardizing on IE and not supporting
Navigator. In many industrial situations, this standardization is now common.

Web Forms

To make Web page construction even easier, Visual Studio .NET supplies Web Forms.
They allow you to build ASP.NET pages graphically in the same way that Visual Basic 6
or C++ Builder windows are created; in other words, by dragging controls from a toolbox
onto a form, then flipping over to the code aspect of that form, and writing event handlers
for the controls. When you use C# to create a Web Form, you are creating a C# class that
inherits from the Page base class, and an ASP.NET page that designates that class as its
code-behind. Of course, you don’t have to use C# to create a Web Form; you can use
Visual Basic .NET or another .NET language just as well.

In the past, the difficulty of Web development has discouraged some teams from
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
attempting it. To succeed in Web development, you had to know so many different
technologies, such as VBScript, ASP, DHTML, JavaScript, and so on. By applying the
Form concepts to Web pages, Web Forms have made Web development considerably
easier.

Web controls

The controls used to populate a Web Form are not controls in the same sense as ActiveX
controls. Rather, they are XML tags in the ASP.NET namespace that the Web browser
dynamically transforms into HTML and client-side script when a page is requested.

Page 23
C# Programming And .Net Framework

Amazingly, the Web server is able to render the same server-side control in different
ways, producing a transformation that is appropriate to the requestor’s particular Web
browser. This means that it is now easy to write fairly sophisticated user interfaces for
Web pages, without having to worry about how to ensure that your page will run on any
of the available browsers—because Web Forms will take care of that for you. You can
use C# or Visual Basic .NET to expand the Web Form toolbox. Creating a new server-
side control is simply a matter of implementing .NET’s
System.Web.UI.WebControls.WebControl class.

XML Web services

HTML pages account for most of the traffic on the World Wide Web. With XML,
however, computers have a device-independent format to use for communicating with
each other on the Web. In the future, computers may use the Web and XML to
communicate information rather than dedicated lines and proprietary formats such as
Electronic Data Interchange (EDI). XMLWeb services are designed for a service-oriented
Web, in which remote computers provide each other with dynamic information that can
be analyzed and re-formatted, before final presentation to a user. An XMLWeb service is
an easy way for a computer to expose information to other computers on the Web in the
form of XML.

In technical terms, an XMLWeb service on .NET is an ASP.NET page that returns XML
instead of HTML to requesting clients. Such pages have a code-behind DLL containing a
class that derives from the WebService class. The Visual Studio .NET IDE provides an
engine that facilitates Web Service development.

There are two main reasons that an organization might choose to use XMLWeb services.
The first reason is that they rely on HTTP; XMLWeb services can use existing networks
(HTTP) as a medium for conveying information. The other is that because XMLWeb
services use XML, the data format is self-describing, non-proprietary, and platform-
independent.

Creating Windows Forms


Although C# and .NET are particularly suited to Web development, they still offer
splendid support for so-called fat-client or thick-client apps, applications that have to be
installed on the end-user’s machine where most of the processing takes place. This
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
support is from Windows Forms. AWindows Form is the .NET answer to a Visual Basic
6 Form. To design a graphical window interface, you just drag controls from a toolbox
onto a Windows Form.

To determine the window’s behavior, you write event-handling routines for the form’s
controls. AWindows Form project compiles to an executable
that must be installed alongside the .NET runtime on the end user’s computer. Like other
.NET project types, Windows Form projects are supported by both Visual Basic .NET
and C#. We examine Windows Forms more closely in Chapter 19.

Page 24
C# Programming And .Net Framework

Windows Controls
Although Web Forms and Windows Forms are developed in much the same way, you use
different kinds of controls to populate them. Web Forms use Web Controls, and
Windows Forms use Windows Controls. AWindows Control is a lot like an ActiveX
control. After a Windows control is implemented, it compiles to a DLL that must be
installed on the client’s machine. In fact, the .NET SDK provides a utility that creates
a wrapper for ActiveX controls, so that they can be placed on Windows Forms. As is the
case with Web Controls, Windows Control creation involves deriving from a particular
class, System.Windows. Forms.Control.

Windows Services

AWindows Service (originally called an NT Service) is a program that is designed to run


in the background in Windows NT/2000/XP/2003 (but not Windows 9x). Services are
useful where you want a program to be running continuously and ready to respond to
events without having been explicitly started by the user. A good example would be the
World Wide Web Service on Web servers, which listens out for Web requests from
clients. It is very easy to write services in C#. There are .NET Framework base classes
available in the System.ServiceProcess namespace that handle many of the boilerplate
tasks associated with services, and in addition, Visual Studio .NET allows you to create a
C# Windows Service project, which uses C# source code for a basic Windows service.

1.2.18 The Role of C# in the .NET Enterprise Architecture

C# requires the presence of the .NET runtime, and it will probably be a few years before
most clients— particularly most home computers—have .NET installed. In the meantime,
installing a C# application is likely to mean also installing the .NET redistributable
components. Because of that, it is likely that we will see many C# applications first in the
enterprise environment. Indeed, C# arguably presents an outstanding opportunity for
organizations that are interested in building robust, n-tiered client-server applications.
When combined with ADO.NET, C# has the ability to access quickly and generically
data stores like SQL Server and Oracle databases.

The returned datasets can easily be manipulated using the ADO.NET object model, and
automatically render as XML for transport across an office intranet. Once a database
schema has been established for a new project, C# presents an excellent medium for
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
implementing a layer of data access objects, each of which could provide insertion,
updates, and deletion access to a different database table. Because it’s the first
component-based C language, C# is a great language for implementing a business object
tier, too. It encapsulates the messy plumbing for inter-component communication,
leaving developers free to focus on gluing their data access objects together in methods
that accurately enforce their organizations’ business rules. Moreover, with attributes, C#
business objects can be outfitted for method level security checks, object pooling, and JIT
activation supplied by COM+ Services.

Page 25
C# Programming And .Net Framework

Furthermore, .NET ships with utility programs that allows your new .NET business
objects to interface with legacy COM components. To create an enterprise application
with C#, you create a Class Library project for the data access objects and another for the
business objects. While developing, you can use Console projects to test the methods on
your classes. Fans of extreme programming can build Console projects that can be
executed automatically from batch files to unit test that working code has not been
broken.

On a related note, C# and .NET will probably influence the way you physically package
your reusable classes. In the past, many developers crammed a multitude of classes into a
single physical component because this arrangement made deployment a lot easier; if
there was a versioning problem, you knew just where to look. Because deploying .NET
enterprise components simply involves copying files into directories, developers can now
package their classes into more logical, discrete components without encountering “DLL
Hell.”

Last but not least, ASP.NET pages coded in C# constitute an excellent medium for user
interfaces. Because ASP.NET pages compile, they execute quickly. Because they can be
debugged in the Visual Studio .NET IDE, they are robust. Because they support full-scale
language features like early binding, inheritance, and modularization, ASP.NET pages
coded in C# are tidy and easily maintained.

Seasoned developers acquire a healthy skepticism about strongly hyped new technologies
and languages and are reluctant to utilize new platforms simply because they are urged
to. If you’re an enterprise developer in an IT department, though, or if you provide
application services across the World Wide Web, let us assure you that C# and .NET
offer at least four solid benefits, even if some of the more exotic features like XMLWeb
services and server-side controls don’t pan out:

1. Component conflicts will become infrequent and deployment is easier, because


different versions of the same component can run side by side on the same
machine without conflicting.
2. Your ASP.NET code won’t look like spaghetti code.
3. You can leverage a lot of the functionality in the .NET base classes.
4. For applications requiring a Windows Forms user interface, C# makes it very easy
to write this kind of application.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Windows Forms have to some extent been downplayed in the last year due to the advent
of Web Forms and Internet-based applications. However, if you or your colleagues lack
expertise in JavaScript, ASP, or related technologies, then Windows Forms are still a
viable option for creating a user interface with speed and ease. Just remember to factor
your code so that the user interface logic is separate from the business logic and the data
access code. Doing so will allow you to migrate your application to the browser at some
point in the future if you need to do so. Also, it is likely that Windows Forms will remain
the dominant user interface for applications for use in homes and small businesses for a
long time to come.

Page 26
C# Programming And .Net Framework

1.2.19 COM+

The following table describes COM+ services and other functionality available to .NET
Framework classes, arranged by topic.
You can modify any CLS-compliant class to use COM+ services. The
System.EnterpriseServices namespace provides custom attributes and classes for
accessing these services from managed code.

Topic Description
AutomaticTransaction Applies declarative transaction-processing features.
Processing
BYOT (Bring Your Own Allows a form of transaction inheritance.
Transaction)
COM Transaction Integrator Encapsulates CICS and IMS applications in Automation
(COMTI) objects.
Compensating Resource Applies atomicity and durability properties to non-
Managers (CRMs) transactional resources.
Just-In-Time Activation Activates an object on a method call and deactivates when
the call returns.
Loosely Coupled Events Manages object-based events.
Object Construction Passes a persistent string value to a class instance on
construction of the instance.
Object Pooling Provides a pool of ready-made objects.
Private Components Protect components from out-of-process calls.
Queued Components Provides asynchronous message queuing.
Role-Based Security Applies security permission based on role.
SOAP Services Publish components as a XML Web services.
Synchronization Manages concurrency.
XA Interoperability Supports the X/Open transaction-processing model.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY

Page 27
C# Programming And .Net Framework

1.2.20 The Base Classes

There are many more namespaces, and the best way to learn about them and the classes
they contain is to explore them yourself - and Microsoft have provided a tool for just this
purpose.

1.2.21 CLR Debugger

The Microsoft CLR Debugger (DbgCLR.exe) provides debugging services with a


graphical interface to help application developers find and fix bugs in programs that
target the common language runtime. The CLR Debugger, and the accompanying

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
documentation, is based on work being done for the Microsoft Visual Studio .NET
Debugger. As a result, the documentation refers mostly to the Visual Studio Debugger,
rather than the CLR Debugger. In most cases, the information is applicable to both
debuggers. However, you will find sections of the documentation describing some
features that are not implemented in the CLR Debugger (see the next paragraph). You
can simply ignore these features and sections.

Here are some of the main differences between the CLR Debugger and the Visual Studio
Debugger as described in the documentation:

Page 28
C# Programming And .Net Framework

The CLR Debugger does not support the debugging of Win32 native code applications.
Only applications written and compiled for the common language runtime can be
debugged with the CLR Debugger.

Remote debugging is not implemented in the CLR Debugger.


The Registers window is implemented in the CLR Debugger, but no register information
appears in the window. Other operations that involve registers or pseudoregisters, such as
displaying or changing a register value, are not supported.

The Disassembly window is implemented in the CLR Debugger but shows the
disassembly code that would be generated for the application if it were compiled as
Win32 native code rather than common language runtime code.
The CLR Debugger does not support F1 help.

CLR Debugger Solution Model

The CLR Debugger uses solutions to associate source files and the applications being
debugged. A solution is created automatically when you open a compiled application and
its associated source file or files. The next time you debug the same application, you can
open the solution instead of having to load the source file and the compiled application
separately. To open an application for debugging (the first time)
Start the CLR Debugger; run DbgCLR.exe, which is in the GuiDebug directory of your
.NET Frameworks installation.

From the Debug menu, select Program to Debug.


In the Program to Debug dialog box, go to the Program box and click the ellipsis button
(…). The Find Program to Debug dialog box appears.
Navigate to the directory containing the EXE you want to debug and select the EXE.
Click Open.
This takes you back to the Program to Debug dialog box. Notice that the Working
directory has been set to the directory containing your EXE.
In the Arguments box, type any arguments that your program requires.
Click OK.
From the File menu, choose Open, then click File.
In the Open File dialog box, choose the source file you want to open.
Click OK.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
To open additional source files, repeat steps 8-10.
This process automatically creates a solution for your debugging session. If you select
Start or Step, the Save File As dialog box opens so you can save the solution. If you
select Exit or Close Solution, a message box appears which prompts you to save the
solution first.

Page 29
C# Programming And .Net Framework

1.3 Revision points

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
The Common Language Runtime

Central to the .NET Framework is its runtime execution environment, known as the
Common Language Runtime (CLR) or the .NET runtime. Code running under the control
of the CLR is often termed managed code

Language interoperability

The use of IL not only enables platform independence; it also facilitates language
interoperability.

Page 30
C# Programming And .Net Framework

Visual Basic .NET

Visual Basic .NET has undergone a complete revamp from Visual Basic 6 to bring it up-
to-date with .NET.

Visual C++ .NET

Visual C++ 6 already had a large number of Microsoft-specific extensions on Windows.

COM and COM+

Technically speaking, COM and COM+ aren’t technologies targeted at .NET, because
components based on them cannot be compiled into IL

Common Type System

This data type problem is solved in .NET through the use of the Common Type System
(CTS).

Common Language Specification


The Common Language Specification (CLS) works with the CTS to ensure language
interoperability
CLR Debugger

The Microsoft CLR Debugger (DbgCLR.exe) provides debugging services with a


graphical interface to help application developers find and fix bugs in programs that
target the common language runtime.

1.4 Intext Questions

1. Explain the .Net Frame work with Block Diagram?


2. What are the components of the .Net Platform?
3. Describe the salient features of C # (C Sharp)?
4. What are Methods?
5. What do you understand by the term CLR Debugger?
6.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Write notes on COM+ serviced available in .Net Framework?

1.5 Summary

 The important aspects of the .NET Framework and C#’s relationship to it.
 How all languages that target .NET are compiled into Microsoft intermediate
language (IL) before this is compiled and executed by the Common Language
Runtime (CLR). Features of .NET in the compilation and execution process:
 Assemblies and .NET base classes .
 COM components

Page 31
C# Programming And .Net Framework

 JIT compilation
 Application domains
 Garbage Collection
 How C# can be used as the basis for applications that are built upon several .NET
technologies, including ASP.NET.

1.6 Terminal Exercises


1.Explain the features of CLR?
2. Central to the .NET Framework is its runtime execution environment, known as the
_______
3. Instead of compiling the entire application in one go the ____ compiler simply
compiles each portion of code as it is called _______
4. The use of IL not only enables platform independence; it also facilitates language
_____
5. The ______ is .NET’s answer to memory management, and in particular to the
question of what to do about reclaiming memory that running applications ask for.

1.7 Supplementary Materials


1. www.amazon.com/Programming-Public-Beta-Simon-Robinson/dp/1861004877
2. support.apress.com/books.asp
3. www.developerfusion.co.uk/forums/thread

1.8 Assignments
1.Case Study: Comparison .Net with J2EE
2.Analyze the performance of CLR debugger

1.9 Reference Books


1. Burton Harvey,Simon Robinson, Julian Templeman and Karli Watson, “C#
Programming with the Public Beta “, Shroff Publishers & Distributors Pvt.Ltd ,Mumbai
April 2001.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
2. Ben Albahart, Peter Drayton and Brad Merrill, C# Essentials “, SPD Mumbai March
2001.
3. “Microsoft C# Language Specifications – WP Publications & Distributors Pvt Ltd.,
Bangalore 2001.

1.10 Learning Activities


Learn .Net COM and DCOM and Create a component in C#.

Page 32
C# Programming And .Net Framework

1.11 Keywords
CLS –Common Language Specification
CLR –Common Language Runtime
CTS –Common Type System
C# - C Sharp
XML – Extensible Markup Language
HTML – Hyper Text Markup Language
COM -Component Object Model
DCOM -Distributed Component Object Model
IDE - Integrated Development Environment

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY

Page 33
C# Programming And .Net Framework

UNIT - II

2.0 Introduction
Having Understood the .NET Environment and its Features, in this chapter let us learn
the fundamentals of C# Programming. The C# compiler are developed in .Net. The .Net
is compared with all languages like C,C++,Java,VB,Delphi and scripting languages. The
basic data types also discussed in this chapter. The program control flow like if
,if..else,/switch and other loops also discussed. The major feature of reflection and
interoperability is discussed.

2.1 Objective
The main objective of this chapter is understand about what is c# and its introduction,
development of C#, Comparison of c# with other languages, the applications can be
developed by c# and very strong knowledge about data types, operators, flow controls,
classes and reflection. It gives a good idea about interoperability and preprocessor.

2.2 Contents
2.2.1 C# Fundamentals

Having Understood the .NET Environment and its Features, in this chapter let us learn
the fundamentals of C# Programming. In this chapter we will know about the structure of
C# Program and various classes ,methods and object declaration before we explore the
features of C# and writes an application.

2.2.2 TheDevelopment of C#

To understand the true significance of C#, you need to understand its historical context.
In this section, we'll review the evolution of different kinds of programming languages,
showing how C# is related to each one.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
The Advent of Assembler

A bit (binary digit) is the smallest unit of information that can be represented inside a
computer. Indeed, you can conceive of computer memory as a long, continuous line of
bits with values of 1 or 0. By feeding sequences of these bits to a digital computer's
processor, you can instruct that processor to perform basic arithmetic and logical
operations such as addition, subtraction, multiplication, and comparisons.

By chaining millions of these simple instructions together, you can make a computer

Page 34
C# Programming And .Net Framework

behave in complex and useful ways. Initially, programming a digital computer's bits
meant physically connecting and disconnecting wires inside the processor so that it would
behave differently.

With the advent of the von Neumann design, instructions could be stored in computer
memory for later execution. Each processor instruction would be stored as a different set
of 1s and 0s. 11110000, for example, might be the instruction for adding two different
values together, while 1111 000 1 might signal the processor to perform subtraction.

As you might imagine, storing such sequences of 1s and 0s in memory for later execution
was a tedious error-prone, and time-consuming process. The introduction of assembly
language expedited this process by allowing programmers to refer to processor operations
by easier-to-remember mnemonics. For example, in assembly language, 11110000 could
be replaced by the symbol ADD, or 11110001 symbolized by the assembly instruction
SUB.

An assembly language programmer could write his program using these easy-to-
remember mnemonics and then run his program through an assembler program, which
would translate the mnemonic instructions into their 1 and 0 equivalents (op codes).

.NET is not the only platform to employ an intermediate language format. Java does, too,
and refers its compiled format as Java "byte code." In the Microsoft world, the
intermediate language format is variously known as "IL" (Intermediate Language),
"MSIL" (Microsoft Intermediate Language), and occasionally "CIL" (Common
Intermediate Language).

2.2.3 The First Compliers

Although writing assembly language was certainly easier than coding 1s and 0s, it still
forced I programmers to think of their programs in terms of individual instructions. It was
still very difficult for a programmer to think of his or her code in higher degrees of
abstraction. Simple conventions that today's programmers take for granted, such as a
loop, might require coding dozen or more assembly language instructions. With
assembly language, programmers wasted a lot of time writing the same patterns of
mnemonics over and over again. Making a computer do something, useful with assembly
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
language required a lot of blood, sweat, and tears.

The time was right for the advent of "higher-level" languages. FORTRAN was the first.
With FORTRAN, a programmer could write his or her code with fewer, more abstract
instructions, and the submit these instructions to a compiler program, which would
translate each high-level instruction into several dozen, hundred, or thousand machine
language instructions.

Therefore, programmers could focus on what their programs did, rather than on the
specific, mind numbing details of the machine code instructions that accomplished them.
Additionally, because higher level languages, such as FORTRAN, were a step removed

Page 35
C# Programming And .Net Framework

from the actual machine's hardware, programs written in a high-level language could be
ported to any machine for which a suitable compiled had been derived.

The output of the first pass, for example, might be a parse tree in memory, in which the
hierarchical relationship between operators and operands was broken down. In the second
pass, the program might walk each node of the parse tree, using something called "syntax
directed translation" to crank out a version of the program in an intermediate language
closely resembling assembler. In the third pass, the program could use the intermediate
language to produce assembly language that could then be easily assembled into machine
code.

2.2.4 The C Programming Language

C was invented while Ken Thompson and Dennis Ritchie of Bell Labs developed the
UNIX operating system. First, they developed a partial C compiler, then used this
compiler to compile the rest of the C compiler, and then used the completed compiler to
compile UNIX. The Unix operating system was Initially distributed as C source code to
universities and laboratories that wanted it, and the recipient would compile that source
code to machine code with a C compiler appropriate to his mainframe.

Being distributed in C source code was what made the UNIX operating system unique;
the operating system could be modified by programmers, and the source code was
portable from hardware system to hardware system. Today, the POSIX standard defines a
standard set of UNIX system calls accessible from C that UNIX implementations seeking
PO SIX-compliant status must implement. C was the third language that Thompson and
Ritchie developed in the UNIX effort; the first two were, of course, "A" and "B."

C Vs C++

In the hands of an experienced programmer, C and C++ are elegant tools for writing
powerful all programs that run very efficiently. In the hands of a less experienced
programmer - or even a good programmer having a bad day - the languages can be quite
error prone. Some of the most common bugs are listed below.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Programming Windows in C and C++

C was originally intended for the UNIX world of batch files, daemon processes, and
redirectable input and output streams. The marriage of C and C++ to the Windows
operating system was one fraught with complexity.

Unlike UNIX, Windows is an event driven operating system. The operating system
constantly polls interrupts for information from the graphical user interface: mouse
clicks, mouse moves, keystrokes, and so on. When a window receives such a message
from the user, the Windows operating system has to route the message to that window
through a message pump.

Page 36
C# Programming And .Net Framework

A window is by its very nature hierarchical. A typical Windows application might


consist, for example, of a main window containing several document windows each of
which contains a several buttons, each of which is also a window, ad infinitum. Writing
such an application in C requires nesting several functions together so that their switch. . .
case constructions bubble operating system messages from the lowest level windows up
to the higher level windows that can act upon them. As you might imagine, such C code
can be messy, convoluted, and bug-prone.

In developing its products, Microsoft did its best to combat C is fussiness. First,
Microsoft developed their own C compilers for in-house use and outfitted these compilers
with state-of-the-art debuggers that could "step-through" code line-by line. Second, they
standardized defensive coding practices such as asserts, debugging prints, and Hungarian
naming conventions. Third, they adopted a development regimen that kept the bugs at
bay by emphasizing daily builds and close interaction between the programmers and
testers.

Microsoft hoped that the move to C++ would make Windows programming less difficult
for themselves and for other development companies. After all, wrapping functions into
classes would seem a good way to organize an API that had swelled to literally thousands
of calls. Unfortunately, Microsoft C++ failed to achieve popularity with the masses. The
Microsoft Foundation Classes (the MFC) never achieved the popularity that they hoped
that it would, and most MFC programs were strewn with cryptic constants and macros.

2.2.5 Enter VB

Although initially regarded as a toy, Microsoft's Visual Basic eventually took the
programming world by storm. Its popularity is due to two things: its relative simplicity,
and its productivity. While it's true that Visual Basic programs don't run quite as quickly
as their C/C++ counterparts, they run quickly enough for most business situations and
require a lot less time to develop.

Forms were the labor-saving abstraction that VB provided to Windows programmers.


The VB IDE allowed you to design windows graphically, by dragging controls, such as
buttons and list boxes from a toolbox, and dropping them onto a form. When you were
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
happy with the appearance of your form, you could flip over to its code aspect and write
event handling routines for each of the form's controls.

Application development in VB thus consisted of the creation of several forms that talked
to each other and perhaps queried a database for persisted information. In effect, a form
was a wrappered window that exposed windows methods in a friendlier way.

VB also reduced bugs by eliminating some of the more esoteric elements of C/C++
syntax. Except in special cases, statements were restricted to single lines, and variables
had to be declared, and initialized in separate statements. The assignment and comparison

Page 37
C# Programming And .Net Framework

operators used the same character, but VB's grammar dictated that these operators be
used in a way that made their intent clear.

Perhaps most importantly, there were no pointers - a requirement that Bill Gates had
made since the I earliest versions of Microsoft BASIC. Although valuable because they
allow programmers direct access to any address in memory, pointers are prone to bugs
unless they are used very carefully. BASIC's emphasis on grammatical simplicity and
clarity go back to the fact that BASIC was first designed as a learning language:

"Beginner's All-purpose Symbolic Instructional Code." By Version 6, VB had matured


into a powerful language that you could use to create distributed applications using COM
components and Microsoft Transaction Server. Microsoft touted the "threetiered"
approach to client-server architectures, in which "thin" user interfaces communicated
with remote VB components, to query data from a database on another machine.
With VBScript and VB for Applications, you could even script web browsers and
automate Microsoft Office applications. Furthermore, you could use VB6 to create
Active-X controls that would run inside.

Internet Explorer, although this was seldom done in practice because it required that the
VB runtime DLL be installed on the web surfer's machine. Although VB programs after
VB5 did compile to machine code, they relied on this runtime DLL to provide them with
commonly used routines and to implement VB's object facilities. Interestingly, VB's';
compiler took the multi-pass approach to translation, and relied on Microsoft's C++
compiler to output the final executable code once an intermediate representation was
derived. In VB's reliance on a runtime and its sharing of the C++ back-end you can
recognize the seeds of .NET.

Despite VB's power, it still had its drawbacks, Specifically, advanced programmers often
encountered things that VB just wouldn't easily do, such as multithreading. Entire books
were written on how to make VB do hardcore things that only C programmers would
normally attempt, such as hooking into the stream of messages that the operating system
delivered to VB forms. Because VB programs relied on a runtime component to provide
much of their functionality, 'they were often slower than equivalent C programs and
required the installation of the VB runtime component on the target machine.

ANNAMALAI
ANNAMALAI UNIVERSITY
2.2.6 Java UNIVERSITY
The needs of information technology were different in the mid-1990's than they had been
in the mid- 1970's when C was introduced. Specifically, the 90's saw a greater emphasis
on distributed applications in which various software components live on disparate
platforms and negotiate with each other for information across local networks and the
Internet. Java was an attempt by Sun Microsystems to meet these new demands. The Java
language brought C++-style syntax into the Internet age.

Java's most remarkable feature is platform independence. Unlike C, C++, and Visual
Basic, Java source code does not compile to machine code (l's and 0's), but to Java byte

Page 38
C# Programming And .Net Framework

code, in which each byte corresponds roughly to a type of machine code instruction
typically supported by most microprocessors., Because there's a layer of abstraction
between a byte code instruction and its machine code equivalent, the same byte code
program can be sent across the Internet for execution on different kinds of computers.

A computer receiving the byte code program is equipped with a "runtime" program that
translates the byte code into machine code instructions for execution. Because the
correspondence between byte code instructions and machine code instructions is roughly
one-to-one, the translation process is fast and byte code programs still execute quickly.

Although Java was originally intended for handheld consumer electronics devices such as
television remote controls, Java became popular as a way to animate web pages. A Java
applet is a byte code program accessed from a web site. When a user with a Java-enabled
browser surfs to a web page with an applet, his or her browser downloads the applet's
byte code and executes it. With the advent of streaming media and technologies such as
Flash, however, Java applets are not quite as popular as they used to be.

Websites use applets to collect order information and present information in entertaining
ways. To prevent computer viruses, the capabilities of Java applets are restricted to a
"sandbox" of features. It is impossible, for example, for a Java applet to write a file to a
host computer's file system. As a Java applet executes, the runtime can dynamically
request needed Java components from the Internet. As the byte code is delivered, the
runtime's byte code verifier would frisk them to guard against malicious behavior.

As Java matured, it came to be used not only for applets but for applications \is well.
Although there had always been Java applications, such as the web browser Hot Java,
Java applications became more feasible with the introduction of Java beans, Java's
answer to COM components. Java beans could live on different machines in a network
and communicate with each other remotely. In addition, Java beans could be endowed
with transacting capabilities, a feature very important in client-server applications.

Java was attractive to application developers who were targeting multiple platforms. If,
for example, you were developing a word processing program that had to run on
Windows machines, Macintosh machines, and Unix machines, wouldn't it be great if you
could write the program once, compile it once, and run it on all of these platforms
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
without any modification? "Write once, run anywhere," was Java's alluring promise.

"Write once, debug everywhere" was the sarcastic retort of burned Java developers who
found out the hard way that Java didn't always port. Sometimes, for example, a Java
program's user interface would render correctly on a Macintosh computer, but incorrectly
on a Windows machine.

Another attractive feature of Java is its availability; you can download the Java SDK
from the Sun site for free. To be truly productive, however, most Java development shops
have to purchase commercial Integrated Development Environments (IDEs) in which to
write their source code. Visual Cafe, Visual Age, and Jbuilder are IDEs that have been

Page 39
C# Programming And .Net Framework

proven popular with the Java crowd. Syntactically, Java is much like C++, but there are
some differences:
 Java does not support pointers because pointers are the source of so many hard-to-
find errors in C++ programs. In Java, objects are always manipulated via
references. Java does not support operator overloading because inappropriate
operator overloading often causes a lot of confusion, particularly in large, multi-
developer efforts.
 Java is completely object-oriented. That is, all functions have to be defined with
in the scope of a class. Because it supported global functions, C++ enabled
programmers to regress to their procedural roots.
 Java comes equipped with an extensive hierarchy of classes that can be used for
windowing, networking, and other problem domains.
 Java encourages the practice of combining a class' declaration and
implementation into the same file.
 The Java runtime provides a garbage collection mechanism that prevents memory
leaks.
 Microsoft hopped on the bandwagon by including J++ in its Visual Studio
development suite. J++ extended Java with some neat features, such as the ability
to automatically generate a COM interface for a Java class when you compile it.

2.2.7 C# Compared to Other Languages

We'll be comparing C# to the other languages available for development. Let's start VB6.

C# Compared to VB

The most obvious difference between C# and VB6, is that C# compiles to MSIL and VB6
compiles to native machine code. Programs written in either language require a runtime
in order to execute. The advantages of the C# runtime are that it allows C# code to
interoperate with code written in other programming languages, and that it allows C#
code to leverage the wealth of functionality afforded by; the .NET base classes.

In terms of features, C# is more object-oriented than VB6. VB6, for example, lacks
parameterized constructors, operator overloading, and implementation inheritance. In
terms of syntax, C# is more concise than VB6, and allows for variables to be
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
simultaneously declared and initialized, and for statements to span an arbitrary number of
lines.

A lot of useful niche market applications have been developed in VB6 by people who
understood the needs of those markets better than they understood programming. If you
are such an entrepreneur / programmer, the great new features of C# and .NET will not
rid your application of the bugs that are in it due to design flaws; if anything, the added
complexities of C# syntax may make a flawed design even more susceptible to bugs.
Also, the reliance of C# programs on the .NET runtime will necessitate deploying the
runtime with all your installations.

Page 40
C# Programming And .Net Framework

Lastly, because VB6 is a mature product with a very wide customer base, Microsoft is
likely to continue supporting it for a long time to come. If your skills have improved a
whole lot since you first wrote your application in VB6, however, and if you feel
confident that you can correct many design flaws by a complete re-write, then you might
consider moving your application from VB6 to C#.

C# Compared to VB.NET

VB.NET can do almost everything that C# can do. The one thing that VB.NET can't do is
allow for embedded blocks of pure C++ code with pointers and other unsafe C++ idioms.

This is a feature that most people won't be interested in, anyway. Just because VB.NET
is powerful however, doesn't mean that it's easy to use. In case you haven't noticed, the
addition of new features to VB has necessitated significant changes to VB's grammar and
syntax. If you're a VB programmer who doesn't have a lot of object-oriented experience,
learning VB.NET will not be a piece of cake.

In coding samples and press blurbs, Microsoft emphasizes C# over VB.NET. Also,
Microsoft plans to rely heavily on C# for future development, and to publicize a C#
standard so that other vendors can develop C# compilers that target other platforms.
These facts imply that VB programmers might be marginalized in the future. On the other
hand, name-recognition for VB is so strong that VB.NET might just marginalize C#.

In reality, it may make little difference whether you choose to use C# or VB.NET. just
don't choose VB,NET with the hopes of making an easy transition, because it won't be.

C# Compared to Visual C++

First of all, C# is simply a flavor of C++. This is implied by the fact that you can embed
chunks of plain C++ in "unsafe" blocks in C# code.

As C# is meant to be more productive than C++, C# prohibits bug-prone C++ idioms:


ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
C# prohibits pointers and pointer arithmetic (except in blocks of unsafe code).
C# eliminates preprocessor macros, (but retains conditional compilation and #defined
constants). Complex macros cause bugs when they expand in unexpected ways around
compound input arguments.

 C# requires that 'a variable be explicitly initialized with a beginning value before
that variable's value can be referenced.
 C# dispenses with fall-through switch. . . case statements. To guard against
programmer oversight, every case clause inside a switch statement must be
accompanied by a closing break command.

Page 41
C# Programming And .Net Framework

 C# forces you to embrace object-oriented programming by eliminating global


functions. Every function in every program must be a member of a class, if only a
static member. Even the opening Main () function is defined as a member of a
class. ,

Because it is interpreted, C# code isn't quite as efficient as C++ code. C# is, however, fast
enough t~ meet the needs of most IT departments, who will welcome the shortened
development cycles that accompany C4F'semphasis on productivity and correctness.
Because C# compiles only to IL and not machine code, it's great stuff for web pages and
business applications but less suitable for device drives and operating system kernels.
Programmers who code straight C++ will have job security for a long time to come. .

One striking advantage of C# is the set of useful data types that it provides you through
the System namespace. Without linking in any separate header files. you have at your
disposal dedicated types for financial values, string values, and Boolean values.
Moreover, because these types are proper classes and not merely primitives, they are each
equipped with useful static methods for conversions and formatting output.

To prevent errors, C# types are "strongly-typed." This means that conversions between
certain data types must be requested explicitly. In C++, it was possible for an integer
value to be implicitly interpreted as a Boolean value. This is not the case in C#. An
integer value would have to be explicated "casted" into a Boolean value in order to be
interpreted in that way.

C# Compared to Managed C++

The .NET runtime component is said to manage client code, providing it with garbage
collection, security checks, and other services. With VS.NET, Microsoft provides a
collection of header files that C++ programmers can use to leverage these services. By
referencing these header files and prefixing the definitions of existing C++ classes with
attributes defined in them, programmers can avail legacy C++ code of the advantages of
the .NET runtime.

If you're a C++ programmer targeting .NET, you probably want to do future development
in C#. The extensions for marrying straight C++ code with the .NET runtime, are most
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
useful for upgrading existing code. Although managed C++ code does allow you to
package managed and unmanaged classes together in the same physical component, you
probably won't have an overwhelming need to do this I very often.

C# Compared to C++ Builder

Borland's C++ development environment, C++ Builder, was most notable for combining
the form approach of user interface design with the C++ language. The advantage of C#
over C++ Builder is that C# has the language interoperability provided by the .NET
runtime. Because programs compiled with C++ Builder are rendered as machine code,
they must rely on COM Services to interoperate with code written in other languages.

Page 42
C# Programming And .Net Framework

C# Compared to Delphi

Delphi, another Rapid Application Development tool from Borland, combined forms with
a proprietary, Pascal-like language. Delphi achieved its greatest popularity before VB6,
when it was the only easy way for programmers who didn't know C++ to create COM
objects and ActiveX controls. With its reliance on BEGIN and END pairs to delimit
statement blocks, Delphi syntax is clumsier and more obtuse than C# syntax. Like C++
Builder, Delphi compiles to machine code and must rely on COM Services for
interoperability; you can't open a Delphi project alongside a VB.NET project and step
through its code with the VS.NET debugger.

When comparing C# to machine-code languages like Delphi and C++ Builder, platform
independence is another factor to consider. Although it's not yet a reality for C#, many
people think that platform independence is coming soon. Because Delphi and C++
Builder don't utilize a byte code, platform independent versions of them are at least one
release away, and would require intense effort on the part of Borland.

C# Compared to Java

There's no doubt that Java was a profound influence on C#. In fact, at least one cynic has
dubbed C# "Cava." Anders Hejlsberg, the leader of the C# effort, also lead the
development of J++, Microsoft's now-defunct Java compiler. The syntax of Java and C#
are similar. Even the structures of the Java library and the .NET base classes are close. Of
course, both languages rely on byte code.

At least at the present time, Java has one strong advantage over C#: platform
independence. Because there are Java runtime implementations for all of the major
computing platforms, the same Java code can theoretically execute on any of them. This
is something that .NET programs can't do-at least not yet.

C# syntax is a bit more powerful than Java's, because C# supports operator overloading
and type-safe enumerations. Also, if the need arises, you have the option of embedding
pointers and other outlawed idioms in your C# programs as long as you enclose them
within "unsafe" blocks.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
In contrast, C# has smaller advantages over Java:

C# inter operates seamlessly with code written in other .NET languages. This means that
an IT department needn't standardize on C# in order to use it in its projects. For this
reason, C# can be seen as a less expensive, less total alternative to Java. The .NET base
classes provide C# with a unified, standardized source for commonly needed
functionality like XML, networking, and graphics. To access the same kinds of
functionality, Java programmers sometimes have to pull from a variety of disparate
sources.

Page 43
C# Programming And .Net Framework

2.2.8 Data Types

As it is known, the basis of any language is the data types it supports. C# has a rich
support for visual data types both built in types such as inheritance and strings and user
defined types such as enumerators, structures and classes. One more point in C# is that,
the variables whichever intrinsic or user defined are first class variables and they can be
used as objects anywhere in the system. These variables are initialized to default values
by the system automatically when they are declared. C# variables are classified into two
simple structures as value types and reference types. Value Types are those variables that
can be assigned a value directly, whereas reference types are variables that are interfaced
through methods or functions to access the internal data. Thus a reference type support
data-hiding which value type does not.

Integral types

The Integral type of C# system is divided into signed and unsigned values. Signed value
types may contain negative or positive value while unsigned will contain positive values.
The conversion between these 2 types requires an explicit cast. This is unlike C++, which
prevents the programmer in making mistake in code and even it is convenient to track
down.

The Sbyte and Byte types

Bytes are used to store very small numbers such as month, delivery etc or an individual
element from file. The Sbyte and byte represent a single byte. In byte values are used for
serialization efforts, signal values. As pointers are used in C#, bytes are used to index a
string. Pointer to remember is that bytes have restriction of 8 bits of precision. a long
string with outflow the index.

The Short value

Short value range from –32767 to 32767.Unsigned short value ranges from 0 to 65535.
Int type. It is 32 bits long and contains values in the range of – 2147,483,648 to 2147,
483,647.unit contain a range of 0 to 4,294,767,295.
C# supports eight predefined integer types:

Name
ANNAMALAI
ANNAMALAI UNIVERSITY
CTS Type
UNIVERSITY Description Range
Sbyte System.SByte 8-bit signed -128 to 127(-2 7 to 27 -1)
integer
Short System.Int16 16-bit signed -32768 to 32767(-2 15 to 215 -1)
integer
Int System. Int32 32-bit signed -2147483648 to 2147483647 (-2 31 to
integer 231 -1)
Long System. Int64 64-bit signed -9223372036854775808 to
integer 9223372036854775807 (-263 to 263 -1)
Byte System.Byte 8-bit unsigned 0 to 255 (0 to 28 -1)

Page 44
C# Programming And .Net Framework

integer
Ushort System.UInt16 16-bit unsigned 0 to 65535 (0 to 216 -1)
integer
Uint System.UInt32 32-bit unsigned 0 to 4294967295 (0 to 232 -1)
integer
Ulong System.UInt64 64-bit unsigned 0 to 18446744073709551615 (0 to 264 -
integer 1)

C# Floating point types

Name CTS Type Description Significant Range (approx)


Figures
Float System.single 32–bit single-precision 7 ±1.5 x 10-45 to ±3.4 x 1038
floating point
Double System.Doubl 64-bit double-precision 15/16 ±5.0 x 10-324 to ±1.7 x 10308
e floating point

Name CTS Type Description Significant Figures Range (approx)


Decimal System.Decimal 128-bit high 28 ±1.0 x 10-28 to ±7.9 x 1028
precision decimal
notation

Name CTS Type Values


Bool System.Boolean True or False

Name CTS Type Values


Char System. Char Represents a single 16-bit (Unicode) character

Long type

It is still longer than Int and reserves 64 bits. Long type can contain values from –
9,223,372,036,854,775 to 9,223,372,036,854,775,808.similarly value have a range of 0 to
18,446,744,073,709,551,615.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Floating point type

It is divided into 2 types: single and double floats. Float variable can have up to 7 digits.
The float data type holds values ranging from 1.5 * 10-45 to 3.4 8 * 10 38. The double
data type is larger than float data type and contain 15 digits. The float variable can range
from 5 * 10 –324 to 1.7 * 10 308. By default floating point number is double. It should be
specified if it is to be a float with character ( f). as float f = 1.4 f.

Page 45
C# Programming And .Net Framework

Decimal type
The decimal data type is used for precision calculation normally currency conversion.
This allows a range of 1.0 * 10-28 to 7.9 * 10 28.

Boolean Type

The Boolean type in C# contains values true or false. We cannot convert bool values
from an integer or to a float .it is an error if it is used 0 or non zero for true and false.

Character type

Char data type is used to store a value of string. These are 16 bits long

Object type

In C# the intrinsic and user defined types are derived from object type. Object types are
used as reference. To bin an object to any other Sub – type. Object type also implements
a number of basic, general purpose methods which Equals ()
GetHashCode( )
GetType( )
ToString()
The type of data the method will return when executed, consider the following
declaration
void myMethod ( ); This return type is void and takes no parameters. In C# either the
return type or void must be declared.

Comments

The comment always are helpful to handle the errors and debugging in any programming
language. This is also a good programming practice. In C# the comment are passed with
the forward slashes( //). This is adopted if there is a single line comment when we have to
declare comment we use the C –style comment ie slash followed by asterik(/*) are end
with an asterik followed by slash.( * /)

2.2.9 Program Control Flow


ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Selection Statements

We use selection statements to determine what code should be executed and when it
should be executed. C# features two selection statements: the switch statement, used to
run code based on a value, and the if statement which runs code based on a Boolean
condition. The most commonly used of these selection statements is the if statement.

Page 46
C# Programming And .Net Framework

The if Statement
The if statement executes one or more statements if the expression being evaluated is
true. The if statement’s syntax follows—the square brackets denote the optional use of
the else statement

if (expression)
statement1
[else
statement2]

Here, expression is any test that produces a Boolean result. If expression results in true,
control is passed to statement1. If the result is false and an else clause exists, control is
passed to statement2. Also note that statement1 and statement2 can consist of a single
statement terminated by a semicolon (known as a simple statement) or of multiple
statements enclosed in braces (a compound statement). The following example code
describes a compound statement being used if expression1 resolves to true:

if (expression1)
{
statement1
statement2
}

In the following example, the application requests that the user type in a number between
1 and 10. A Precise number is then generated, and the user is told whether the number
they picked matches the Precise number. This simple example illustrates how to use the if
statement in C#.

using System;
class Ifsol1App
{
const int MAX = 10;
public static void Main()
{
Console.Write(“Guess a number between 1 and {0}...”, MAX);
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
string inputString = Console.ReadLine();
int userGuess = inputString.ToInt32();
Precise rnd = new Precise();
double correctNumber = rnd.NextDouble() * MAX;
correctNumber = Math.Round(correctNumber);
Console.Write(“The correct number was {0} and we guessed {1}...”,
correctNumber, userGuess);
if (userGuess == correctNumber) // They got it right!
{
Console.WriteLine(“Congratulations!”);
}

Page 47
C# Programming And .Net Framework

else // Wrong answer!


{
Console.WriteLine(“Maybe next time!”);
}
}
}

Multiple else Clauses

The if statement’s else clause enables we to specify an alternative course of action should
the if statement resolve to false. In the number-guessing example, the application
performed a simple compare between the number the user guessed and the Precisely
generated number. In that case, only two possibilities existed: the user was either correct
or incorrect. We can also combine if and else to handle situations in which we want to
test more than two conditions. In the example below, I ask the user which language he or
she is currently using (excluding C#). I’ve included the ability to select from three
languages, so the if statement must be able to deal with four possible answers: the three
languages and the case in which the user selects an unknown language. Here’s one way
of programming this with an if/else statement:

using System;
class Ifsol2App
{
const string CPlusPlus = “C++”;
const string VisualBasic = “Visual Basic”;
const string Java = “Java”;

public static void Main()


{
Console.Write(“What is wer current language of choice “ +
“(excluding C#)?”);
string inputString = Console.ReadLine();
if (0 == String.Compare(inputString, CPlusPlus, true))
{
Console.WriteLine(“\nWe will have no problem picking “ +
ANNAMALAI
ANNAMALAI UNIVERSITY
“up C# !”);
}
UNIVERSITY
else if (0 == String.Compare(inputString, VisualBasic, true))
{
Console.WriteLine(“\nWe will find lots of cool VB features “ +
“in C# !”);
}
else if (0 == String.Compare(inputString, Java, true))
{
Console.WriteLine(“\nWe will have an easier time “ +
“picking up C# <G> !!”);

Page 48
C# Programming And .Net Framework

}
else
{
Console.WriteLine(“\nSorry - does not compute.”);
}
}
}

Note the use of the == operator to compare 0 to the returned value of String.Compare.
This is because String.Compare will return -1 if the first string is less than the second
string, 1 if the first string is greater than the second, and 0 if the two are identical.
However, this illustrates some interesting details, described in the following section,
about how C# enforces use of the if statement.

2.2.10 Enforcing Rules in C#

One aspect of the if statement that catches new C# programmers off guard is the fact that
the expression evaluated must result in a Boolean value. This is in contrast to languages
such as C++ where we’re allowed to use the if statement to test for any variable having a
value other than 0. The following example illustrates several common errors that C++
developers make when attempting to use the if statement in C# for the first time:

using System;
interface ITest
{
}

class TestClass : ITest


{
}

class InvalidIfApp
{
protected static TestClass GetTestClass()
{ ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
return new TestClass();
}

public static void Main()


{
int bag = 1;
if (bag) // ERROR: attempting to convert int to bool.
{
}

Page 49
C# Programming And .Net Framework

TestClass t = GetTestClass();
if (t) // ERROR: {
Console.WriteLine(“{0}”, t);
ITest i = t as ITest;
if (i) // ERROR {
}
}
}
}

As we have observed, the compiler throws error three times in response to three attempts
to use the if statement with an operation that does not yield a Boolean value. The reason
for this is that the C# designers want to help we avoid ambiguous code and believe that
the compiler should enforce the original purpose of the if statement—that is, to control
the flow of execution based on the result of a Boolean test. The example above is
rewritten below to compile without error. Each line that caused the compiler error in the
previous program has been modified to contain an expression that returns a Boolean
result, thereby appeasing the compiler.

using System;
interface ITest
{
}

class TestClass : ITest


{
}

class ValidIfApp
{
protected static TestClass GetTestClass()
{
return new TestClass();
}

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
public static void Main()
{
int bag = 1;
if (bag > 0)

{
}

TestClass t = GetTestClass();
if (t != null)
{

Page 50
C# Programming And .Net Framework

Console.WriteLine(“{0}”, t);
ITest i = t as ITest;
if (i != null)
{
// ITest methods.
}
}
}
}

2.2.11The switch Statement

Using the switch statement, we can specify an expression that returns an integral value
and one or more pieces of code that will be run depending on the result of the expression.
It is similar to using multiple if/else statements, but although we can specify multiple
(possibly unrelated) conditional statements with multiple if/else statements, a switch
statement consists of only one conditional statement followed by all the results that the
code is prepared to handle. Here’s the syntax:

switch (switch_expression)
{
case constant-expression:
statement
jump-statement

case constant-expressionN:
statementN
[default]
}

Conceptually, the switch statement works just as the if statement does. First, the
switch_expression is evaluated, and then the result is compared to each of the constant-
expressions or case labels,defined in the different case statements. Once a match is made,
control is passed to the first line of code in that case statement.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
There are two main rules to keep in mind here. First, the switch_expression must be of
the type (or implicitly convertible to) sbyte, byte, short, ushort, int, uint, long, ulong,
char, or string (or an enum based on one of these types). Second, we must provide a
jump-statement for each case statement unless that case statement is the last one in the
switch, including the break statement. Because this works differently than in several
other languages.

In addition to letting us specify different case statements, the switch statement also allows
for the definition of a default statement. This is like the else clause of an if statement.
There can be only one default label for each switch statement and that if no appropriate

Page 51
C# Programming And .Net Framework

case label is found for the switch_expression, control is passed to the first line of code
after the switch statement’s ending brace. Here’s an example—a Payment class is using
the switch statement to determine which tender has been selected:

using System;
enum Tenders : int
{
Cash = 1,
VBCard,
CanCard,
UnitedExpressCard
};

class Payment
{
public Payment(Tenders tender)
{
this.Tender = tender;
}

protected Tenders tender;


public Tenders Tender
{
get
{
return this.tender;
}
set
{
this.tender = value;
}
}

public void ProcessPayment()

{ ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
switch ((int)(this.tender))
{
case (int)Tenders.Cash:
Console.WriteLine(“\nCash - Accepted”);
break;

case (int)Tenders.Vbcard:
Console.WriteLine(“\nVbCard - Accepted”);
break;
case (int)Tenders.CanCard:

Page 52
C# Programming And .Net Framework

Console.WriteLine(“\nCancard - Accepted”);
break;
case (int)Tenders.UnitedExpressCard:
Console.WriteLine(“\nUnitedExpressCard - Accepted”);
break;
default:
Console.WriteLine(“\nSorry - Invalid tender”);
break;
}
}
}

class SwitchApp
{
public static void Main()
{
Payment payment = new Payment(Tenders.Vb);
payment.ProcessPayment();
}
}

Running this application results in the following output because we instantiated the
Payment class by passing it a value of Tenders.Vb:
VbCard - Accepted.

2.2.12 Combining Case Labels

The above example, we used a different case label for each possible evaluation of the
Payment.tender field. However, if we want to combine case labels, we might want to
display a credit card authorization dialog box for any of the three credit card types
deemed valid in the Tenders enum. In that case, we could place the case labels one right
after the other, like so:

using System;
enum Tenders : int
{ ANNAMALAI
ANNAMALAI UNIVERSITY
Cash = 1,
UNIVERSITY
Vb,
CanCard,
UnitedExpressCard
};

class Payment
{
public Payment(Tenders tender)
{

Page 53
C# Programming And .Net Framework

this.Tender = tender;
}

protected Tenders tender;


public Tenders Tender
{
get
{
return this.tender;
}
set
{
this.tender = value;
}
}

public void ProcessPayment()


{
switch ((int)(this.tender))
{
case (int)Tenders.Cash:
Console.WriteLine
(“\nCash - Everyone’s favorite tender.”);
break;
case (int)Tenders.Vb:
case (int)Tenders.CanCard:
case (int)Tenders.UnitedExpress:
Console.WriteLine
(“\nDisplay Credit Card Authorization Dialog.”);
break;
default:
Console.WriteLine(“\nSorry - Invalid tender.”);
break;
}
}
} ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
class CombiningCaseLabelsApp
{

public static void Main()


{
Payment payment = new Payment(Tenders.CanCard);
payment.ProcessPayment();
}
}

Page 54
C# Programming And .Net Framework

If we instantiate the Payment class with Tenders.Vb, Tenders.CanCard, or


Tenders.UnitedExpress, we will get this output:

Display Credit Card Authorization Dialog.

During the design phase of C#, its designers were cognizant of applying a “risk/reward”
test when deciding whether a feature should be included in the language. The fall-through
feature is an example of one that did not pass the test. Normally in C++, a case statement
runs when its constant-expression matches the switch_expression. The switch statement
is then exited with a break statement. Fall-through causes the next case statement in the
switch statement to execute in the absence of a break statement. C# does not support fall-
through, is typically used in situations in which we have two case labels and the second
label represents an operation that will be done in either case. Analyze the following:

// C++ menu.
switch(itemSelected)
{
case TABLE:
case TREE_VIEW:
break;
}

The first case label amounts to a combination of the two labels without me having to
duplicate code or insert two calls to the same method. By far, the C# language designers
decided that although this feature can be handy, its reward wasn’t worth the risk involved
because the majority of the time a break statement is left out unintentionally, which
results in bugs that are difficult to track down.
if (itemSelected == TABLE)
{
// Add menu options based on current table.
}

2.2.13 Iteration Statements

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
In C#, the while, do/while, for,and foreach statements enable we to perform controlled
iteration, or looping. In each case, a specified simple or compound statement is executed
until a Booleanexpression resolves to true, except for the case of the foreach statement,
which is used to iterate through a list of objects.

The while Statement

The while statement takes the following form:


while (Boolean-expression)
embedded-statement

Page 55
C# Programming And .Net Framework

Using the number-guessing example from earlier chapter, we could rewrite the example,
as beginning with a while statement such that we could continue the game until we either
guessed the correct number or decided to quit.

using System;
class WhiltrApp
{
const int MIN = 1;
const int MAX = 10;
const string EXIT_CHAR = “Q”;

public static void Main()


{
Precise rnd = new Precise();
double correctNumber;

string inputString;
int userGuess;

bool rightGuess = false;


bool userQuit = false;

while (!rightGuess && !userQuit)


{
correctNumber = rnd.NextDouble() * MAX;
correctNumber = Math.Round(correctNumber);
Console.Write
(“Guess a number between {0} and {1}...({2} to quit)”,
MIN, MAX, EXIT_CHAR);
inputString = Console.ReadLine();
if (0 == string.Compare(inputString, EXIT_CHAR, true))
userQuit = true;
else
{
userGuess = inputString.ToInt32();
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
rightGuess = (userGuess == correctNumber);
Console.WriteLine
(“The correct number was {0}\n”,
correctNumber);
}
}

if (rightGuess && !userQuit)


{
Console.WriteLine(“Congratulations!”);
}

Page 56
C# Programming And .Net Framework

else

{
Console.WriteLine(“Maybe next time!”);
}
}
}

Coding and running this application will result in output similar to the following:
C:\>WhiltrApp
Guess a number between 1 and 10...(Q to quit)3
The correct number was 5
Guess a number between 1 and 10...(Q to quit)5
The correct number was 5

Congratulations!
C:\>WhiltrApp
Guess a number between 1 and 10...(Q to quit)q
Maybe next time!

The do/while Statement

Reminding the syntax for the while statement, we can see the possibility for one
problem. The Boolean-expression is evaluated before the embedded-statement is
executed. For this reason, the application in the previous section initialized the
rightGuess and userQuit variables to false to guarantee that the while loop would be
entered. From there, those values are controlled by whether the user correctly guesses the
number or quits. However, what if we want to make sure that the embedded-statement
always executes at least once without having to set the variables artificially. The do/while
statement is used for this purpose.

The do/while statement takes the following form:


do
embedded-statement
while ( Boolean-expression )
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Since the evaluation of the while statement’s Boolean-expression occurs after the
embedded-statement, we’re sure that the embedded-statement will be executed at least
one time. The number-guessing application rewritten to use the do/while statement
appears on the following page.

using System;
class DoWhiltrApp
{
const int MIN = 1;
const int MAX = 10;

Page 57
C# Programming And .Net Framework

const string EXIT_CHAR = “Q”;

public static void Main()


{
Precise rnd = new Precise();
double correctNumber;

string inputString;
int userGuess = -1;

bool userHasNotQuit = true;


do
{
correctNumber = rnd.NextDouble() * MAX;
correctNumber = Math.Round(correctNumber);
Console.Write
(“Guess a number between {0} and {1}...({2} to quit)”,
MIN, MAX, EXIT_CHAR);
inputString = Console.ReadLine();
if (0 == string.Compare(inputString, EXIT_CHAR, true))
userHasNotQuit = false;
else
{
userGuess = inputString.ToInt32();
Console.WriteLine
(“The correct number was {0}\n”, correctNumber);
}
} while (userGuess != correctNumber
&& userHasNotQuit);
if (userHasNotQuit
&& userGuess == correctNumber)
{
Console.WriteLine(“Congratulations!”);
}
else // wrong answer!
ANNAMALAI
ANNAMALAI UNIVERSITY
{ UNIVERSITY
Console.WriteLine(“Maybe next time!”);
}
}
}

The functionality of this application will be the same as the while sample. The only
difference is how the loop is controlled. In practice, we will find that the while statement
is used more often than the do/while statement. However, because we can easily control
entry into the loop with the initialization of a Boolean variable, choosing one statement
over the other is a choice of personal preference.

Page 58
C# Programming And .Net Framework

The for Statement

The most common iteration statement that is used is the for statement. The for statement
is made up of three parts. One part is used to perform initialization at the beginning of the
loop—this part is carried out only once. The second part is the conditional test that
determines whether the loop is to be run again. And the last part, called “stepping,” is
typically used to increment the counter that controls the loop’s continuation—this counter
is what is usually tested in the second part. The for statement takes the following form:

for (initialization; Boolean-expression; step)


embedded-statement

The three parts (initialization, Boolean-expression, step) can be empty. When Boolean-
expression evaluates to false, control is passed from the top of the loop to the next line
following the embedded-statement. Therefore, the for statement works just like a while
statement except that it gives the additional two parts (initialization and step). This is an
example of a for statement that displays the printable ASCII characters:

using System;
class ForSolApp
{
const int OpenChar = 23;
const int CloseChar = 225;

static public void Main()


{
for (int i = OpenChar; i <= CloseChar; i++)
{
Console.WriteLine(“{0}={1}”, i, (char)i);
}
}
}

The order of events for this for loop is as follows:


ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
A value-typevariable (i) is allocated on the stack and initialized to 23. Note that this
variable will be out of scope once the for loop concludes.
The embedded statement will execute while the variable i has a value less than 226. In
this example, we have used a compound statement. However, because this for loop
consists of a single line statement, we could also write this code without the braces and
get the same results.

After each iteration through the loop, the variable i will be incremented by 1.

Page 59
C# Programming And .Net Framework

Nested Loops

In the embedded-statement of a for loop, we can also have other for loops, which are
generally referred to as nested loops. Using the example from the previous section, I’ve
added a nested loop that causes the application to print three characters per line, instead
of one per line:

using System;
class NestedIsApp
{
const int OpenChar = 23;
const int CloseChar = 225;
const int CharactersPerLine = 3;

static public void Main()


{
for (int i = OpenChar; i <= CloseChar; i+=CharactersPerLine)
{
for (int j = 0; j < CharactersPerLine; j++)
{
Console.Write(“{0}={1} “, i+j, (char)(i+j));
}
Console.WriteLine(“”);
}
}

Note that the variable i that was defined in the outer loop is still in scope for the internal
loop. However, the variable j is not available to the outer loop.

The foreach Statement

The foreach looping statements is new for programmers other than VB.The foreach
statement allow us to iterate through all the items in an array or in other collections. C#
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
also has such a construct, the foreach statement, which takes the following syntax.

foreach (type in expression)


embedded-statement

Take a look at the following array class:


class ThisArray
{
public ArrayList words;
public ThisArray()
{

Page 60
C# Programming And .Net Framework

words = new ArrayList();


words.Add(“bag”);
words.Add(“pouch”);
words.Add(“case”);
}
}

From the different iteration statements we have already seen, we know that this array can
be traversed using any of several different statements. However, to most Java and C++
programmers, the most logical way to write this application would be like this:

using System;
using System.Collections;

class ThisArray
{
public ArrayList words;
public ThisArray()
{
words = new ArrayList();
words.Add(“bag”);
words.Add(“pouch”);
words.Add(“case”);
}
}

class ForeachApp
{
public static void Main()

{
ThisArray ThisArray = new ThisArray();
for (int i = 0; i < ThisArray.words.Count; i++)
{
Console.WriteLine(“{0}”, ThisArray.words[i]);

}
ANNAMALAI
ANNAMALAI UNIVERSITY
} UNIVERSITY
}

But this approach is warrants with potential problems: If the for statement’s initialization
variable (i) isn’t initialized properly, the entire list will not be be iterated and the for
statement’s Boolean expression isn’t correct, the entire list wil not be be iterated. Also
the for statement’s step is not correct, the entire list will not be iterated. Collections and
arrays have different methods and properties for accessing their count. Collections and
arrays have different semantics for extracting a specific element. The for loop’s
embedded statement needs to extract the element into a variable of the correct type.

Page 61
C# Programming And .Net Framework

With the foreach statement, the previous code would be rewritten as follows:

using System;
using System.Collections;

class ThisArray
{
public ArrayList words;
public ThisArray()
{
words = new ArrayList();
words.Add(“bag”);
words.Add(“pouch”);
words.Add(“case”);
}
}

class Foreach2App
{
public static void Main()
{
ThisArray ThisArray = new ThisArray();
foreach (string word in ThisArray.words)
{
Console.WriteLine(“{0}”, word);
}
}
}

Notice how much more intuitive using the foreach statement is. We are guaranteed to get
every element because we don’t have to manually set up the loop and request the count,
and the statement automatically places the element in a variable that we name. We need
only refer to the variable in the embedded statements.

2.2.14 Branching with Jump Statements


ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
we can control the flow of execution of any of the iteration statements by embedding
statements of covered in the previous sections, with one of several statements collectively
known as jump statements: break, continue, goto, and return.

The break Statement

We use the break statement to terminate the current enclosing loop or conditional
statement in which it appears. Control is then passed to the line of code following that
loop’s or conditional statement’s embedded statement. Having the simplest syntax of any

Page 62
C# Programming And .Net Framework

statement, the break statement has no parentheses or arguments and takes the following
form at the point that we want to transfer out of a loop or conditional statement:
break

In the following example, the application will print each number from 1 to 100 that is
equally divisible by 6. However, when the count reaches 66, the break statement will
cause the for loop to discontinue.

using System;
class BreakSolApp
{
public static void Main()

{
for (int i = 1; i <= 100; i ++)
{
if (0 == i % 6)
{
Console.WriteLine(i);
}

if (i == 66)
{
break;
}
}
}
}

Breaking Out of Infinite Loops

Another use for the break statement is to create an infinite loop in which control is
transferred out of the loop only by a break statement being reached.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
The following statement has changed the while statement to while (true) such that it will
not end until a break statement is encountered.

using System;
class InfLoopApp
{
const int MIN = 1;
const int MAX = 10;
const string EXIT_CHAR = “Q”;

public static void Main()

Page 63
C# Programming And .Net Framework

{
Precise rnd = new Precise();
double correctNumber;

string inputString;
int userGuess;
bool rightGuess = false;
bool userQuit = false;

while(true)
{
correctNumber = rnd.NextDouble() * MAX;
correctNumber = Math.Round(correctNumber);
Console.Write
(“Guess a number between {0} and {1}...({2} to quit)”,
MIN, MAX, EXIT_CHAR);
inputString = Console.ReadLine();
if (0 == string.Compare(inputString, EXIT_CHAR, true))
{
userQuit = true;
break;
}
else
{
userGuess = inputString.ToInt32();
rightGuess = (userGuess == correctNumber);
if ((rightGuess = (userGuess == correctNumber)))
{
break;
}
else
{

Console.WriteLine
(“The correct number was {0}\n”, correctNumber);
ANNAMALAI
ANNAMALAI UNIVERSITY
}
} UNIVERSITY
}
if (rightGuess && !userQuit)
{
Console.WriteLine(“Congratulations!”);
}
else
{
Console.WriteLine(“Maybe next time!”);
}

Page 64
C# Programming And .Net Framework

}
}

The continue Statement

Like the break statement, the continue statement enables us to alter the execution of a
loop. However, instead of ending the current loop’s embedded statement, the continue
statement stops the current iteration and returns control back to the top of the loop for the
next iteration. In the following example, the array of strings to be checked for duplicates.
One way to accomplish that is to iterate through the array with a nested loop, comparing
one element against the other. Therefore, if one index into the array (i) is the same as the
other index into the array (j), it means that we have the same element and do not want to
compare those two. In that case, we use the continue statement to discontinue the current
iteration and pass control back to the top of the loop.

using System;
using System.Collections;

class ThisArray
{
public ArrayList words;
public ThisArray()
{
words = new ArrayList();
words.Add(“bag”);
words.Add(“case”);
words.Add(“pouch”);
words.Add(“case”);
words.Add(“case”);
words.Add(“bag”);
}
}

class ContinueApp
{ ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
public static void Main()
{
ThisArray ThisArray = new ThisArray();
ArrayList dupes = new ArrayList();

Console.WriteLine(“Processing array...”);
for (int i = 0; i < ThisArray.words.Count; i++)
{
for (int j = 0; j < ThisArray.words.Count; j++)

Page 65
C# Programming And .Net Framework

{
if (i == j) continue;
if (ThisArray.words[i] == ThisArray.words[j]
&& !dupes.Contains(j))
{
dupes.Add(i);
Console.WriteLine(“’{0}’ appears on lines {1} and {2}”,
ThisArray.words[i],
i + 1,
j + 1);
}
}
}
Console.WriteLine(“There were {0} duplicates found”,
((dupes.Count > 0) ? dupes.Count.ToString() : “no”));
}
}

Notice that we could have used a foreach loop to iterate through the array. However, in
this particular case, we wanted to keep track of which element we were on, so using a for
loop was the best way.

goto Statement

Probably no other construct in programming history is as maligned as the goto statement.


Therefore, before we get into the syntax for and some uses of the goto statement, let us
look at why some people feel so strongly about not using this statement and the types of
problems that can be solved by using it. The problem with using goto is not the keyword
itself—rather, it is the use of goto in inappropriate places. The goto statement can be a
useful tool in structuring program flow and can be used to write more expressive code
than that resulting from other branching and iteration mechanisms. One such example is
the “loop-and-a-half” problem, as coined by Dijkstra. Here is the traditional flow of the
loop-and-a-half problem in pseudocode:
loop
read in a value
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
if value == sentinel then exit
process the value
end loop

The exit from the loop is accomplished only by the execution of the exit statement in the
middle of the loop. This loop/exit/end loop cycle, however, can be quite disturbing to
some people who, acting on the notion that all uses of goto are evil, would write this code
as follows:
read in a value
while value != sentinel
process the value

Page 66
C# Programming And .Net Framework

read in a value
end while

This second approach has two major drawbacks. First, it requires the duplication of the
statement(s) required to read in a value. Any time we duplicate code, this results in an
obvious maintenance problem in that any change to one statement must be made to the
other. The second problem is more subtle and probably more damning.

The key to writing solid code that’s easy to understand, and therefore maintain, is to write
code that reads in a natural manner. In any noncode description of what this code is
attempting to do, one would describe the solution as follows: First, we need to read in a
value. If that value is a sentinel, we stop. If not, we process that value and continue to the
next value.

Therefore, it is the code omitting the exit statement that’s actually counterintuitive
because that approach reverses the natural way of thinking about the problem. Now, let
us look at some situations in which a goto statement can result in the best way to
structure control flow.

Using the goto Statement

The goto statement can take any of the following forms:


goto identifier
goto case constant-expression
goto default

In the first usage of the goto statement here, the target of the identifer is a label statement.
The label statement takes the form
identifer:

If that label does not exist in the current method, a compile-time error will result. Another
important rule to remember is that the goto statement can be used to jump out of a nested
loop. However, if the goto statement is not within the scope of the label, a compile-time
error will result. Therefore, we cannot jump into a nested loop. In the following example,
the application is iterating through a simple array, reading each value until it reaches a
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
sentinel value whereupon it exits the loop. Notice that the goto statement really just acts
like the break statement in that it causes the program flow to jump out of the foreach
loop.

using System;
using System.Collections;
class ThisArray
{
public ArrayList words;
public const string TerminatingWord = “stop”;

Page 67
C# Programming And .Net Framework

public ThisArray()
{
words = new ArrayList();
for (int i = 1; i <= 5; i++) words.Add(i.ToString());
words.Add(TerminatingWord);
for (int i = 6; i <= 10; i++) words.Add(i.ToString());
}
}

class Goto1App
{
public static void Main()
{
ThisArray ThisArray = new ThisArray();
Console.WriteLine(“Processing array...”);
foreach (string word in ThisArray.words)
{
if (word == ThisArray.TerminatingWord) goto finished;
Console.WriteLine(word);
}

finished:
Console.WriteLine(“Finished processing array”);
}
}

Regarding this use of the goto statement, one could argue that a break statement could
have been used just as effectively and a label wouldn’t have been necessary. We will look
at the other forms of the goto statement, and we will see that the problems at hand can be
resolved only with the goto statement.

In the section on the switch statement, We discussed the fact that fall-throughs are not
supported in C#. Even if fall-throughs were supported, it would not solve the following
problem. Let us say we have a Payment class (reused from earlier in the chapter) that
accepted several forms of payment, or tenders: Vbcard, United Express, CanCard, cash,
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
and charge off (basically a credit). Because Vb, United Express, and CanCard are all
credit cards, we could combine them into a single case label and process them all in the
same manner. In the case of the charge off, we would need to call methods specific to it,
and in the case of the cash purchase, we would only want to print a receipt. Also, we
would want to print a receipt in all cases. How could we have three distinct case labels
but have the first two cases—the credit card and the charge back cases—both branch to
the cash label when done? The following code, this problem is a good example of when
to use the goto statement:

using System;
enum Tenders : int

Page 68
C# Programming And .Net Framework

{
ChargeOff,
Cash,
Vbcard,
CanCard,
UnitedExpress
};

class Payment
{
public Payment(Tenders tender)
{
this.Tender = tender;
}

protected Tenders tender;


public Tenders Tender
{
get
{
return this.tender;
}

set
{
this.tender = value;
}
}

protected void ChargeOff()


{
Console.WriteLine(“Charge off.”);
}

protected bool ValidateCreditCard()


{ ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Console.WriteLine(“Card approved.”);
return true;
}

protected void ChargeCreditCard()


{
Console.WriteLine(“Credit Card charged”);
}

protected void PrintReceipt()

Page 69
C# Programming And .Net Framework

{
Console.WriteLine(“Thank we and come again.”);
}

public void ProcessPayment()


{
switch ((int)(this.tender))
{
case (int)Tenders.ChargeOff:
ChargeOff();
goto case Tenders.Cash;

case (int)Tenders.Vbcard:
case (int)Tenders.CanCard:
case (int)Tenders.UnitedExpress:
if (ValidateCreditCard())
ChargeCreditCard();
goto case Tenders.Cash;
case (int)Tenders.Cash:
PrintReceipt();
break;

default:
Console.WriteLine(“\nSorry - Invalid tender.”);
break;
}
}
}

class GotoCaseApp
{
public static void Main()
{
Payment payment = new Payment(Tenders.Vbcard);
payment.ProcessPayment();

}
} ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Instead of having to solve the problem counterintuitively, we simply tell the compiler that
when a credit card or charge off case is finished, we want to branch to the cash label. One
last thing to note here is that if we branch out of a case label in C#, we should not use a
break statement, which would result in a compiler error for “unreachable code.” The last
form of the goto statement enables us to branch to the default label in a switch statement,
thereby giving we another means of writing a single code block that can be executed as a
result of multiple evaluations of the switch statement.

Page 70
C# Programming And .Net Framework

The return Statement

The return statement has two functions. It specifies a value to be returned to the caller of
the currently executed code (when the current code is not defined as returning void), and
it causes an immediate return to the caller. The return statement is defined with the
following syntax:

return [ return-expression ]

When the compiler encounters in a method, a return statement that specifies a return-
expression, it evaluates whether the return-expression can be implicitly converted into a
form compatible with the current method’s defined return value. It is the result of that
conversion that is passed back to the caller. When using the return statement with
exception handling, we have to be sure that we understand some rules. If the return
statement is a try block that contains an associated finally block, control is actually
passed to the first line of the finally block, and when that block of code finishes, control
is passed back to the caller. If the try block is nested in another try block, control will
continue back up the chain in this fashion until the final finally block has executed.

2.2.15 Reflection

As assemblies are self-describing and stores meta-data, including details of all the types
and member of these types. It is possible to access this metadata programmatically using
.NET basic classes in the name space. This technology is known as reflection which
reflects the user input can be utilized .we can select classes to instantiate methods to call
at runtime rather than compiling.

2.2.16 Console applications

The program myfirstprogram.cs in C# is an example of a console program. Console


applications will have no user interface(UI). There will be no list boxes, buttons,
windows etc. the input and output is handled by standard system console.
In the example quoted in chapter1 myfirstprogram.cs, Main ( ) mentioned prints the text
“My First program” on the monitor. The monitor is managed by an object named
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
console. This console object has a method Writeline() when takes a string and writes to
the standard output. When this program runs a DOS screen will popup and display “ My

First program in C#” in the console window.


A (.) operator is used to invoke a method. Thus in WriteLine() method we write
console.WriteLine() to call the console objects.

Name Spaces

The .NET framework library contains thousands of names such as Array list, Event. For
each class, it is obvious that no programmer can memorise all the names. In C# each class

Page 71
C# Programming And .Net Framework

name should be unique. Conflict occurs when we create a class with the name of an
already existing class. Thus this poses a never ending problem.The class can be renamed
but that would not be prudent decision. The solution for this problem is to create a
namespace, which restricts a name’s scope,making it meaningful only within the defined
namespace. A clarification is made so that the namespace is meaningful without another
namespace. For example in name space System, the console object is restricted. The goal
of namespaces is to divide the components of the object hierarchy.

The dot Operator (.)

The dot operator is used to access the data and method in a class and to restrict the class
name to a particular namespace. Consider the following.
class my First Program
{
static void main ( )
{
System .Console .WriteLine (“My First Program”);
}
}

In this, the system namespace is the help level and console object exists within this name
space and WriteLine() method is a member function of console type.

Using Keyword

In the above example, we have used System.Console. Instead we can specify just
Console.WriteLine() in the code by including the using keyword with the namespace at
the beginning of the file as given below.
Using System;
At the top of the program. Thus above program can be written as

Using System;
Class My First Program
{
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
static void main ( )
{
Console .WriteLine(“My first Program in C# “ );
}
}

Page 72
C# Programming And .Net Framework

Case Sensitivity

C# is case sensitive .That means it reads the small and upper case distinctly (i.e.) System
is not system. C# does not fix these errors .Thus to prevent these errors; a naming
convention should be followed for naming the variables function, constants etc.

Compiling and running a program

So far we have seen the overview of .NET framework and of C# language and
understood framework features and C# Language fundamentals and basics. Before we
proceed to learn in depth let us see how to save, compile and run a C# program.
We can adopt two ways to write a program, compile and run in C#. One using the Visual
Studio.NET IDE and other using the text editor and a command line compiler.

2.2.17 Visual Studio.NET

If you want the maximum in productivity in the .NET environment, you should use
Visual Studio.NET. Not only does it provide all the integrated tools and wizards for
creating C# applications, but it also includes productivity features such as IntelliSense
and Dynamic Help. With IntelliSense, as you type in a namespace or class name,
members are automatically displayed so that you don’t have to remember every member
of every class. IntelliSense also displays all arguments and their types when you type in
the name of a method and an opening parenthesis. Visual Studio 6 also provides this
capability, but obviously it does not support the .NET types and classes. Dynamic Help is
a feature new to Visual Studio. While you are typing code into the editor, a separate
window displays topics related to the word the cursor is in. For example, if you type the
keyword namespace, the window shows hyperlinks to help topics covering the usage of
the namespace keyword.

Basic Requirements needed to begin C# Programming

 .NET Framework Software Development Kit and


 An Editor (like Notepad or DOS Editor) to write source codes.

ANNAMALAI
ANNAMALAI UNIVERSITY
 Optional
UNIVERSITY
Visual C#. NET or
Requirements: -

 Visual C++ 6.0 included with Visual Studio 6.0

Installing .NET Framework SDK

As a first step you should install .NET SDK on your computer to begin C# Programming.
It can be downloaded from the Microsoft’s Website. It is also available with almost all
the popular computing magazine CD’S. It also comes with the complete documentation

Page 73
C# Programming And .Net Framework

in the form of HTML Help. Official release of .NET Framework SDK 1.1 is available
and it can be downloaded from downloads.microsoft.com. The SDK comes with
compilers, linkers and various other tools that help to compile the code written in C#,
VB.NET and C#.NET.

You can also develop applications with C# and Visual Basic by using Visual Studio.NET
languages like Visual C#.NET and Visual Basic.NET. This will help you to develop
windows based applications easily and with limited effort because you don’t have to
devote too much time in designing the user interface (Usage of WinForms). The only
work left for you to do is to write the codings appropriately as per the .NET Standards.

About the Editors


Notepad is the best choice among developers using .NET SDK to develop C#
applications. However it is not the most suitable editor since it does not support syntax
coloring, code numberings etc. Developers can use Visual C++ 6.0 included with Visual
Studio 6.0. However they should make some tweaking in the registry before using the
same. It supports syntax colorings and other features such as finding line numbers
(Ctrl+G). However it is dangerous for a new user to make changes in registry. Hence
only advanced and experienced users can be able to use Visual Studio 6.0 for developing
C#. It is not possible to compile and execute the applications from the Visual C++ 6.0
Environment. Hence there is not much use except some of the features listed above.
VisualStudio.NET provides all the integrated tools and wizards for creating C# and
Visual Basic applications. It also supports features such as intellisense, Dynamic help.
Moreover you can compile and execute your applications from the IDE itself. Hence in
order to experience the power of developing the .NET applications, you should try
VisualStudio.NET.

Many Third Party editors are now available either from magazine’s CD’S or can be
downloaded from the internet. However it is up to you to decide upon which editor to
use. I recommend you to try one common editor and learn the language in full.

Compiling in Command mode.

Getting Started with Hello C#

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Steps to compile and run a program
The program is written in a notepad or text editor and saved with a file extension .cs(c
sharp). All C# program is saved with .cs extension.

Open the command window (Start -> run -> type cmd/command).
In the command editor (DOS prompt) type CSC myfirsdtprogram.cs. this builds an
executable (EXE) file.

To run the program type myfirstprogram


The output is displayed as “my first C# program”

Page 74
C# Programming And .Net Framework

After understanding the fundamentals of .NET and its structure, let us now move on to
look at a classic Hello C# Program. As I mentioned in the previous tutorial, you can use
any text editor as per your convenience.

Simple Hello C# Program.


Using System;
class Hello {
public static void Main() {
Console.WriteLine (“Hello C#”);
}
}

Save the following file as Hello.cs. cs is an extension to indicate C# like .java for a Java
source file. You have to supply this extension while saving your file, otherwise the code
will not compile correctly. The saved file will be of .cs.txt extension.Compile the above
code by giving the following command at the command prompt csc Hello.cs. If there are
compile errors then you will be prompted accordingly, otherwise you will be getting a
command prompt with the copyright information. Keep in mind that the compiler
generates MSIL.Your next job is to execute the program to view the final output. For that
purpose you have to simply give Hello at the command Prompt. If everything goes on
well, a message Hello C# will be printed on the Screen.

You can view the MSIL code generated by any .NET Language with the help of an
Utility called Intermediate Language Disassembler or shortly ILDASM. This utility will
display the application’s information in a tree like fashion. Since the contents of this file
are read only, a programmer or anybody accessing these files cannot make any
modifications to the output generated by the source code.
To view the MSIL code for the above Hello C# Program, open Hello.exe file from the
ILDASM tool. In Windows 98, ME & NT this tool can be accessed via start - programs -
Microsoft .NET Framework SDK-Tools-ILDisassembler.

Detailed explanation of the above Program: -

we are analyzing below the process occurring to the source code, during the compilation
and execution stages once again for your reference.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Compilation Stage: -C# Compiler produces MSIL as output after compilation. It is itself
a complete language and it is more or less similar to Assembly language. MSIL stands for
Microsoft Intermediate Language. The same thing happens to any application written in
any CLR Compliant Language like VisualBasic.NET,VisualC++.NETetc.

Execution Stage: -The MSIL is then compiled into native CPU instructions by using JIT
(Just in Time) compiler at the time of the program execution. The Source Code is
recompiled and executed only after making any changes to it.

Page 75
C# Programming And .Net Framework

Now let us analyze the Hello C# Program as a whole. I am giving below the code once
again for your reference. Please note that the line numbers are given for clarification and
explanation and is not a part of the Source Code.
Line Number wise Analysis

Line1 : Using System;


Line2 : Class Hello {
Line3 : Public static void Main () {
Line4 : Console.WriteLine (“Hello C#”);
Line5 : }
Line6 : }
Line - 1: - It is called as the namespace. Simply speaking, a namespace is a collection of
.NET classes similar to packages in Java.
Line – 2: - It is the class declaration similar to Java & C++
Line – 3: - This is the main method which is required in all C# applications.
Line – 4: - This code will print Hello C# onto the Console. Here Console is the class
belonging to System namespace and writeLine is the static method belonging to Console
class.
Line -5&6 :- The Opening and Closing curly races are similar to that of C++/Java.

2.2.18 Classes and Objects

In programming the objects & classes are to distinguished. A class is the generic
definition of the object., for example class can be defined as furniture and the objects
will be table a class or cupboard. The furniture class describes the dimensions, material,
color, weight etc. The main advantage of classes in object oriented programming is that
they have the capability of encapsulation through which it becomes a single. A class is
made up of several k different components. A constructor, destructor and methods are all
parts of a class by default. The constructor is called as soon as the object is creates and
destructor is called when the object goes out of scope.

Defining a class
The new type of class is declared first and then the methods and fields. Note that class is
always declared using the class keyword.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
The syntax is as follows.
[attribute] [access-modifier] class identifier [base-class]
{
class great
}

Attributes is a piece of data that attaches itself with the binary component of a class even
after the compile process is executed. It is used to denote information about a class.
Access-modifier determines the access to the methods, member variables within a class.

Page 76
C# Programming And .Net Framework

Access Modifier Description


Signifies that the member is accessible from outside the class’s
public
definition and hierarchy of derived classes.
The member is not visible outside the class and can be accessed
protected
by derived classes only.
The member cannot be accessed outside the scope of the defining
private class. Therefore, not even derived classes have access to these
members.
The member is visible only within the current compilation unit.
Internal The internal access modifier creates a hybrid of public and
protected accessibility depending on where the code resides.

The identifier is the name of the class and the base class is optional. The class body is
made up of member definitions and enclosed in curly braces {} consider the following
program.
public class Fiber
{
public static int main()
{
……..
}
}

Here till now we have not instantiated any instances of that class, ie we have not created a
fiber objects. We have to create an instance of a class and before assigning the value
consider the type int and variable of type int we declare

int coInteger = 5; and not


int = 5;

Then when a new class is declared the properties of all objects of the class and their
behaviour are defined.When we work on a Visual Basic environment we want to create a
screen known as GUI to make the application more user interactive. One control, which
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
will be of interest, is the combinational box enabling the user to type of his choice. The
list box has various features like width, height, color, location and behaviour like open,
close, sorting, etc. In object oriented programming we can check a new type, ListBox
which ensulates the characteristics with member variables namely height, width, location,
hex color and member methods namely sort(), add(), etc.Data can be assigned to ListBox
type by creating an instance of the same.
ListBox CDListBox ;
Once this instance is created the values can be assigned.
Consider this Example

using System;

Page 77
C# Programming And .Net Framework

public class Time


{
//public methods
public void DisplayCurrenrTime ( )
{
Console.WriteLine (
“stub for DisplayCurrentTime”);
}
// private variables
int Year;
int Month;
int Date;
int Hour;
int Minute;
int Second;
}
public class Firstclass
{
static void Main ()
{
Time k = new Time ();
k.DisplayCurrentTime();
}
}

The method declared in this class definition is the DisplayCurrentTime (0.). The Method
body is defined within the class definition. Unlike C++, in C# the method need not be
declared before they are defined. The above DisplayCurrentTime () method returns void
and it will not return any value for the method that invokes it. The period class has
number of member variables like, Year, Month, Date, Hour, Minute and second.
After declaring the variable the braces are closed and subsequently the second class
Display is declared. Display class contains the Main ( ) method. In Main ( ) the Instance
of period is created and the address is defined to object K.As K is an instance of Period,
Main ( ) makes use of the DisplayCurrentTime( ) method available with object of that
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
type and calls to distinguish the period.
K.DisplayCurrentTime ():

2.2.19 Arguments In methods.

Methods can take any number of parameters . The method name is followed by
Parameter List and is Encased in Paranthesis with each parameter preceded by its type.

Example
The following declaration defines a method named method 1 which returns void and
takes two parameters int and button

Page 78
C# Programming And .Net Framework

void method1 (int myparam1, button myparam2)


{
// …
}

The parameter acts as a local variable within the body of the method and behaves as if it
is declared in the body of the method and initializes with the values passed in . the
Example below explains how the values are passed into a method when the value types
are Int and float .
using System;
public class FirstClass
{
public void MyMethod (int myparam1, float myparam2)
{
Console.WriteLine(
“The parameters received are : {0}, {1}”,
myparam1, myparam2);
}
}
public class Tester
{
static void Main()
{
int no = 10;
float p = 4.15f;
FirstClass fc = new FirstClass();
fc.MyMethod(no,p);
}
}

The method MyMethod ( ) takes an int and a float and displays them using
console.WriteLine{ } .The parameters which are named myParam1 and myParam2, are
taken as local variables with MyMethod ( ) .In the calling method (Main ) ,two local
variables ( no ,p) are created and initialized subsequently these variables are passed as the
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
parameters to MyMethod ( ) . the compiler maps variable no to myParam1 and p to
myParam2 based on the relative position in the parameter list.

Page 79
C# Programming And .Net Framework

2.3 Revision points


The Advent of Assembler
A bit (binary digit) is the smallest unit of information that can be represented inside a
computer. Indeed, you can conceive of computer memory as a long, continuous line of
bits with values of 1 or 0.

The C Programming Language

C was invented while Ken Thompson and Dennis Ritchie of Bell Labs developed the
UNIX operating system.

Enter VB

Although initially regarded as a toy, Microsoft's Visual Basic eventually took the
programming world by storm

Java

The needs of information technology were different in the mid-1990's than they had been
in the mid- 1970's when C was introduced.

Data Types

As it is known, the basis of any language is the data types it supports. C# has a rich
support for visual data types both built in types such as inheritance and strings and user
defined types such as enumerators, structures and classes

Iteration Statements

In C#, the while, do/while, for,and foreach statements enable we to perform controlled
iteration, or looping.

Reflection
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
As assemblies are self-describing and stores meta-data, including details of all the types
and member of these types.

Name Spaces

The .NET framework library contains thousands of names such as Array list, Event

Page 80
C# Programming And .Net Framework

2.4 Intext Question


1. What are the Data types used in C# ?
2. What are namespaces?
3. Write a simple program in C# to display “My first program” and analyse the
steps?
4. What are editors?
5. Describe the steps to compile a c# program in command mode?
6. What are the selection statements in C # ?
7. Give an example for switch ststement and explain?
8. What are the Iteration Statements? Explain with appropriate examples?
9. Explain the use of the break Statements?
10. Describe the accesses modifiers in C#?
11. Define a class?
12. Distinguish Classes and Objects ?
13. How will you pass the values in a method when it is a float?

2.5 Summary
a. A bit (binary digit) is the smallest unit of information that can be represented
inside a computer
b. Although writing assembly language was certainly easier than coding 1s and 0s, it
still forced I programmers to think of their programs in terms of individual
instructions.
c. "Beginner's All-purpose Symbolic Instructional Code." By Version 6, VB had
matured into a powerful language that you could use to create distributed
applications using COM components and Microsoft Transaction Server
d. Java's most remarkable feature is platform independence
e. The most obvious difference between C# and VB6, is that C# compiles to MSIL
and VB6 compiles to native machine code.
f. With VS.NET, Microsoft provides a collection of header files that C++
programmers can use to leverage these services
g. C# variables are classified into two simple structures as value types and reference
types.Value Types are those variables that can be assigned a value directly,
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
whereas reference types are variables that are interfaced through methods or
functions to access the internal data.
h. We use the break statement to terminate the current enclosing loop or conditional
statement in which it appears

i. As assemblies are self-describing and stores meta-data, including details of all the
types and member of these types.
j. The .NET framework library contains thousands of names such as Array list,
Event. For each class, it is obvious that no programmer can memorise all the
names.

Page 81
C# Programming And .Net Framework

2.6 Terminal exercises


1. A ____ is the smallest unit of information that can be represented inside a computer
2. C# prohibits _____ C++ idioms:
3. C# variables are classified into two simple structures as _____ and _____ types.
4. The Integral type of C# system is divided into _____ and _____values

2.7 Supplementary Materials


1. www.objectinnovations.com
2. www.itcourseware.com
3. www.pcquest.com

2.8 Assignments
1. Analyse the interoperability.
2. Compare C# with other Languages.

2.9 Reference Books


1.Burton Harvey,Simon Robinson, Julian Templeman and Karli Watson, “C#
Programming with the Public Beta “, Shroff Publishers & Distributors Pvt.Ltd ,Mumbai
April 2001.
2.Ben Albahart, Peter Drayton and Brad Merrill, C# Essentials “, SPD Mumbai March
2001.
3.“Microsoft C# Language Specifications – WP Publications & Distributors Pvt Ltd.,
Bangalore 2001.

2.10 Learning Activities


Learn about the data types available in C# and its Inbuilt Classes

2.11 Key words


ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
MSIL - Microsoft Intermediate Language
IL - Intermediate Language
CIL - Common Intermediate Language).
MFC - Microsoft Foundation Classes

Page 82
C# Programming And .Net Framework

UNIT - III

3.0 Introduction
Visual Studio .NET IDE (Integrated Development Environment) is the Development
Environment for all .NET based applications which comes with rich features. VS .NET
IDE provides many options and is packed with many features that simplify application
development by handling the complexities. Visual Studio .NET IDE is an enhancement to
all previous IDE’s by Microsoft.

3.1 Objectives

The main objective of this chapter is understand about VS .Net IDE, To create Projects
using IDE, after creation of projects compilation, debugging and writing codes to get
more knowledge to write software. The Features of VS.Net also explained.

3.2 Contents

3.2.1 Important Features

One IDE for all .NET Projects

Visual Studio .NET IDE provides a single environment for developing all types of .NET
applications. Application’s range from single windows applications to complex n-tier
applications and rich web applications.

Option to choose from Multiple Programming Languages

You can choose the programming language of your choice to develop applications based
on your expertise in that language. You can also incorporate multiple programming
languages in one .NET solution and edit that with the IDE.

IDE is Customizable

You can customize the IDE based on your preferences. The My Profile settings allow you
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
to do this. With these settings you can set the IDE screen the way you want, the way the
keyboard behaves and you can also filter the help files based on the language of your
choice.

Built-in Browser

The IDE comes with a built-in browser that helps you browse the Internet without
launching another application. You can look for additional resources, online help files,
source codes and much more with this built-in browser feature.

Page 83
C# Programming And .Net Framework

When we open VS .NET from Start->Programs->Microsoft Visual Studio .NET-


>Microsoft Visual Studio .NET the window that is displayed first is the Start Page which
is shown below. The start Page allows us to select from the most recent projects (last four
projects) with which we worked or it can be customized based on your preferences.

The Integrated Development Environment (IDE) shown in the image below is what we
actually work with. This IDE is shared by all programming languages in Visual Studio.
You can view the toolbars towards the left side of the image along with the Solution
Explorer window towards the right.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY

Page 84
C# Programming And .Net Framework

New Project Dialogue Box

The New Project dialogue box like the one in the image below is used to create a new
project specifying it's type allowing us to name the project and also specify it's location
on the disk where it is saved. The default location on the hard disk where all the projects
are saved is

C:\DocumentsandSettings\Administrator\ MyDocuments\ VisualStudioProjects


ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY

Page 85
C# Programming And .Net Framework

Following are different templates under Project Types and their use.

Windows Application: This template allows to, create standard windows based
applications.

Class Library: Class libraries are those that provide functionality similar to Active X
and DLL by creating classes that access other applications.

Windows Control Library: This allows to create our own windows controls. Also called
as User Controls, where you group some controls, add it to the toolbox and make it
available to other projects.

ASP .NET Web Application: This allows to create web-based applications using IIS.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
We can create web pages, rich web applications and web services.

ASP .NET Web Service: Allows to create XML Web Services.

Web Control Library: Allows to create User-defined controls for the Web. Similar to
user defined windows controls but these are used for Web.

Console Application: A new kind of application in Visual Studio .NET. They are
command line based applications.

Page 86
C# Programming And .Net Framework

Windows Service: These run continuously regardless of the user interaction. They are
designed for special purpose and once written, will keep running and come to an end only
when the system is shut down.

Other: This template is to develop other kinds of applications like enterprise


applications, database applications etc.

Solution Explorer Window

The Solution Explorer window gives an overview of the solution we are working with
and lists all the files in the project. An image of the Solution Explorer window is shown
below.

Server Explorer Window

The Server Explorer window is a great tool that provides "drag and drop" feature and
helps us work with databases in an easy graphical environment. For example, if we drag
and drop a database table onto a form, VB .NET automatically creates connection and
command objects that are needed to access that table. The image below displays Server
Explorer window.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY

Page 87
C# Programming And .Net Framework

Intellisense

Intellisense is what that is responsible for the boxes that open as we type the code.
IntelliSense provides a list of options that make language references easily accessible
and helps us to find the information we need. They also complete the typing for us. The
image below displays that.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY

Page 88
C# Programming And .Net Framework

Code Designer Window

Code Designers like the image below allows us to edit and write code. This is the
window that opens when we double-click on a form or any control. This is the place
where we write all the code for the application. Notice the two drop-down list boxes at
the top of the code window in the image below. The left box allows us to select the
object's code we are working with and the right box allows us to select the part of code
that we want to work. Also notice the "+" and "-" boxes in the code designer. You can
use those boxes to display code Visual Basic .NET already created, like, Windows Forms
Designer generated code, etc.

Properties Window

The properties window allows us to set properties for various objects at design time. For
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
example, if you want to change the font, font size, backcolor, name, text that appears on a
button, textbox etc, you can do that in this window. Below is the image of properties
window. You can view the properties window by selecting View->Properties Window
from the main menu or by pressing F4 on the keyboard.

Page 89
C# Programming And .Net Framework

Dynamic Help Window

The dynamic help window displays help which looks up for things automatically. For
example, if you want to get help with a form, select the form and select Help->Dynamic
Help from the main menu. Doing that displays all the information relating to forms. The
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
image below displays that. You can get help relating to anything with this feature. Say, if
you want to know more about the form, select the form and select Dynamic Help from
the Help menu. Doing that displays information about the form as shown in the image
below.

Page 90
C# Programming And .Net Framework

Command Window

The command window in the image below is a useful window. Using this window we can
add new item to the project, add new project and so on. You can view the command
window by selecting View->Other Windows->Command Window from the main menu.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
The command window in the image displays all possible commands with File.

Page 91
C# Programming And .Net Framework

Task List Window

The task list window displays all the tasks that VB .NET assumes we still have to finish.
You can view the task list window by selecting View->Show tasks->All or View->Other
Windows->Task List from the main menu. The image below shows that. As you can see
from the image, the task list displayed "TextBox1 not declared", "RichTextBox1 not
declared". The reason for that message is, there were no controls on the form and
attempts where made to write code for a textbox and a richtextbox. Task list also displays
syntax errors and other errors you normally encounter during coding The class view

Class View Window

window like the image below is the window that presents solutions and projects in terms
of the classes they contain and the members of these classes. Using the class view
window also helps us to find a member of a class that we want to work with. As you can
notice from the image, the class view window displayed all the methods and events for
the controls which were available on the form.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY

Page 92
C# Programming And .Net Framework

Output Window

The output window as you can see in the image below displays the results of building and
running applications.

Object Explorer Window


ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
The object explorer window allows us to view all the members of an object at once. It
lists all the objects in our code and gives us access to them. The image below displays an
object explorer window. You can view the object explorer window by selecting View-
>Other Windows-> Object Browser from the main menu.

Page 93
C# Programming And .Net Framework

Toolbox Window

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
The toolbox window is the window that gives us access to all controls, components, etc.
As you can see from the image below, the toolbox uses tabs to divide it's contents into
categories (Data, Components, Windows Forms and General). The Data tab displays
tools for creating datasets and making data connections, the Windows Forms tab displays
tools for adding controls to forms, the General tab is left empty by default, the Clipboard
Ring tab displays recent items stored in the clipboard and allows us to select from them.

Page 94
C# Programming And .Net Framework

3.2.2 Features of Visual Studio

Refractoring

Making changes to your code like, "pulling a large stretch of inline code into its own
method" or "converting a field to be a property." The Refactoring support makes this easy
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
to do The key tenet of Extreme Programming created by Kent Beck is constant
Refactoring. Under this programming model, you are developing code rapidly and
iteratively, but to keep your code from becoming a jumbled mess, you must constantly
Refactor. Refactoring is a C# only feature

Page 95
C# Programming And .Net Framework

3.2.3 Edit and Continue

Visual Basic has always been about Rapid Application Development (RAD). One key
feature is the ability to fix runtime errors on the fly. With Visual Basic .NET 1.0 and
Visual Basic .NET 1.1, this powerful feature wasn't included. This feature is on-board for
Whidbey. If you run into an exception at runtime, you get an exception helper that
provides tips for fixing common errors, but more importantly, you can edit the code,
select F5, and it continues right where you left off. Edit and Continue is VB .NET only
feature

3.2.4 ClickOnce

ClickOnce make it easy to install applications and provide ongoing updates (Self-
Updating), rather than forcing to distribute new versions of application, can just deploy
the portion of the application which has changed. In the .NET Framework 1.0 and 1.1,
href-exes were not able to solve many deployment issues. Href-exes are also known as
''no-touch deployment, or zero impact deployment''.

Essentially, with versions 1.0/1.1, you can deploy an application to a Web server,
allowing users to browse to the URL for the exe, as in: <a href="someapp.exe"> You can
run me by clicking this link </a> When the user clicks the link, the application
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
downloads to their Internet files cache and runs. To keep this from being a huge security
hole, the application permissions are restricted based on the URL (Intranet applications
get different permissions than Internet applications, for example), or other factors. This
means that some applications no longer need to be deployed in the traditional sense; no
more setup.exe or MSI

href-exes have a number of limitations

 The .NET Framework must be pre-installed on the client machine.


 There's no good way to bootstrap the .NET Framework down if it's not there.

Page 96
C# Programming And .Net Framework

 Most non-trivial applications consist of the main .exe and a number of assembly
files. With href-exes, the assembly files are downloaded on demand, which is
great for corporate Intranet applications, but there's no way to download the
application in one shot so that you know it can be safely used off-line.
 Limited support for versioning.
 The application doesn't hook into Add/Remove Programs, and the application
doesn't install Start menu shortcuts.

ClickOnce deployment differs from href-exes in some significant ways

 ClickOnce applications are self-updating.


 With href-exes you can only make the application self-updating through the use of
custom code or through the use of a component, such as the .NET Application
Updater component.
 With ClickOnce, updates can also be marked as mandatory or optional.
 When applications are installed through ClickOnce, they show up in the start
menu and they can be uninstalled through the '''Add/Remove Programs''' feature.
 ClickOnce works its magic through two XML manifest files.
 The first is an ''application manifest'' and
 The second is a ''deployment manifest''.
 The application manifest describes the application itself, which includes
information about the application assemblies, dependencies, and files that make
up the application. The application manifest also states the required permissions,
and the location where updates can be downloaded.
 The deployment manifest points to the location of the application manifest and
files, and instructs the clients on which version of the application they should be
running.

3.2.5 SmartTags

This provides access to information and common tasks without forcing you to
constantly navigate away from your work area

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY

Page 97
C# Programming And .Net Framework

3.2.6 Code Snippets

With code snippets, you can insert generic "template" code that requires only that you fill
in the blanks. You can access code snippets by right-clicking in the code editor and
navigating in the context menu to Insert Snippets

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY

Page 98
C# Programming And .Net Framework

3.2.7 Exporting IDE Settings

With Whidbey, migrating and persisting IDE settings are a simple process of navigating
to Tools | Import/Export Settings.

3.2.8 Line Revision Marks

Line Revision marks allow you to see the changes you've made during a coding session.
When writing code in the IDE, you'll notice yellow and Lime lines appearing down the
left hand side of the code editor window.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY

Page 99
C# Programming And .Net Framework

To change the color, navigate to '''Tools | Options''' in the IDE, and then choose '''Show
All Settings'''. After that expand '''Environment''' click on the '''Fonts and Colors'''. Scroll
down the '''Display Items'''

 '''Track changes before Save''' - yellow


 '''Track Changes after Save''' - Lime

3.2.9 Temporary Projects

Visual Studio .NET 2002 and Visual Studio .NET 2003 both had a propensity to persist
your temporary ideas as permanent projects on your hard disk. This created the
''WindowsApplication1,2,3...n'' problem. Visual Studio .NET supports the idea of
temporary projects. if you attempt to close the IDE without saving, it will prompt you to
either save or ''discard'' the project

3.3 Revision points

One IDE for all .NET Projects

Visual Studio .NET IDE provides a single environment for developing all types of .NET
applications.

Option to choose from Multiple Programming Languages

You can choose the programming language of your choice to develop applications based
on your expertise in that language.

IDE is Customizable

You can customize the IDE based on your preferences. The My Profile settings allow you
to do this.

ANNAMALAI
ANNAMALAI UNIVERSITY
Built-in Browser
UNIVERSITY
The IDE comes with a built-in browser that helps you browse the Internet without
launching another application.

Windows Application: This template allows to create standard windows based


applications.

Class Library: Class libraries are those that provide functionality similar to Active X
and DLL by creating classes that access other applications.

Page 100
C# Programming And .Net Framework

Windows Control Library: This allows to create our own windows controls. Also called
as User Controls, where you group some controls, add it to the toolbox and make it
available to other projects.

ASP .NET Web Application: This allows to create web-based applications using IIS.
We can create web pages, rich web applications and web services.

ASP .NET Web Service: Allows to create XML Web Services.

Web Control Library: Allows to create User-defined controls for the Web. Similar to
user defined windows controls but these are used for Web.

Console Application: A new kind of application in Visual Studio .NET. They are
command line based applications.

Windows Service: These run continuously regardless of the user interaction. They are
designed for special purpose and once written, will keep running and come to an end only
when the system is shut down.

Other: This template is to develop other kinds of applications like enterprise


applications, database applications etc.

3.4 Intext Question


1. Explain the overview of Vs.net IDE?
2. Explain how to create projects?
3. How can you customize the VS .Net?
4. Explain the features of VS .Net?

3.5 Summary
 Visual Studio .NET IDE provides a single environment for developing all types of
.NET applications.
 You can choose the programming language of your choice to develop applications
based on your expertise in that language.
 ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
You can customize the IDE based on your preferences. The My Profile settings
allow you to do this.
 The IDE comes with a built-in browser that helps you browse the Internet without
launching another application.
 The Solution Explorer window gives an overview of the solution we are working
with and lists all the files in the project
 The Server Explorer window is a great tool that provides "drag and drop" feature
and helps us work with databases in an easy graphical environment.
 Intellisense is what that is responsible for the boxes that open as we type the code.

Page 101
C# Programming And .Net Framework

 Code Designers like the image below allows us to edit and write code. This is the
window that opens when we double-click on a form or any control.
 The properties window allows us to set properties for various objects at design
time

 The dynamic help window displays help which looks up for things automatically.
 The toolbox window is the window that gives us access to all controls,
components, etc.

3.6 Terminal exercises


1. The _________ gives an overview of the solution we are working with and lists all the
files in the project
2. ________ is what that is responsible for the boxes that open as we type the code.
3. The ___________ displays help which looks up for things automatically.
4. The ________ is the window that gives us access to all controls, components, etc.

3.7 Supplementary Materials


1. www.microsoft.com/mspress/books
2. msdn2.microsoft.com/en-us/vcsharp/aa336809.aspx
3. search.barnesandnoble.com/booksearch/isbnInquiry.asp?
4. www.academicresourcecenter.net/curriculum/pfv.aspx

3.8 Assignments
1. Analyse the VS.NET IDE .
2. Compare VS IDE WITH JAVA IDE.

3.9 Reference Books


1. Burton Harvey,Simon Robinson, Julian Templeman and Karli Watson, “C#
Programming with the Public Beta “, Shroff Publishers & Distributors Pvt.Ltd,
Mumbai April 2001.
2. Ben Albahart, Peter Drayton and Brad Merrill, C# Essentials “, SPD Mumbai March
ANNAMALAI
ANNAMALAI UNIVERSITY
2001. UNIVERSITY
3. “Microsoft C# Language Specifications – WP Publications & Distributors Pvt Ltd.,
Bangalore 2001.

3.10 Learning Activities


Learn about the Features of VS.Net

3.11 Key word


RAD -Rapid Application Development.

Page 102
C# Programming And .Net Framework

UNIT - IV

4.0 Introduction
This chapter gives a brief introduction about methods structure with examples and
handing errors ie try..catch blocks are introduced. The namespace classes and types are
also given. The OOP structs are discussed with example. Inheritance , Operator
overloading and Properties, methods and events of an object are also discussed.

4.1 Objectives
The main objective of this chapter is know about the statements, program control, How
to access methods, Handling errors, Namespace, Structs, classes, Enum. It also gives
more knowledge about inheritance, operator overloading properties,methods, events of an
object and delegates.

4.2 Contents

4.2.1 Methods

All of our functionality for each program resided in the Main() method. While this was
adequate for the simple programs we used to learn earlier concepts, there is a better way
to organize your program, using methods. A method helps you separate your code into
modules that perform a given task.

4.2.2 Method Structure

Methods are extremely useful because they allow you to separate your logic into different
units. You can pass information to methods, have it perform one or more statements, and
retrieve a return value. The capability to pass parameters and return values is optional and
depends on what you want the method to do. Here's a description of the syntax required
for creating a method:

attributes modifiers return-type method-name(parameters )


{

}
ANNAMALAI
ANNAMALAI UNIVERSITY
statements UNIVERSITY
The return-type can be any C# type. It can be assigned to a variable for use later in the
program. The method name is a unique identifier for what you wish to call a method. To
promote understanding of your code, a method name should be meaningful and
associated with the task the method performs. Parameters allow you to pass information
to and from a method. They are surrounded by parenthesis. Statements within the curly
braces carry out the functionality of the method.

Page 103
C# Programming And .Net Framework

Program 4-1. One Simple Method: OneMethod.cs


using System;

class OneMethod
{
public static void Main()
{
string myChoice;

OneMethod om = new OneMethod();

do
{
myChoice = om.getChoice();

// Make a decision based on the user's choice


switch(myChoice)
{
case "A":
case "a":
Console.WriteLine("You wish to add an address.");
break;
case "D":
case "d":
Console.WriteLine("You wish to delete an address.");
break;
case "M":
case "m":
Console.WriteLine("You wish to modify an address.");
break;
case "V":
case "v":
Console.WriteLine("You wish to view the address list.");
break;
case "Q":
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
case "q":
Console.WriteLine("Bye.");
break;
default:
Console.WriteLine("{0} is not a valid choice", myChoice);
break;
}

// Pause to allow the user to see the results


Console.WriteLine();
Console.Write("press Enter key to continue...");

Page 104
C# Programming And .Net Framework

Console.ReadLine();
Console.WriteLine();

} while (myChoice != "Q" && myChoice != "q"); // Keep going until the user wants
to quit
}

string getChoice()
{
string myChoice;

// Print A Menu
Console.WriteLine("My Address Book\n");

Console.WriteLine("A - Add New Address");


Console.WriteLine("D - Delete Address");
Console.WriteLine("M - Modify Address");
Console.WriteLine("V - View Addresses");
Console.WriteLine("Q - Quit\n");

Console.Write("Choice (A,D,M,V,or Q): ");

// Retrieve the user's choice


myChoice = Console.ReadLine();
Console.WriteLine();

return myChoice;
}
}

The program in Program 4-1 is similar to the DoLoop program from Lesson 4, except for
one difference. Instead of printing the menu and accepting input in the Main() method,
this functionality has been moved to a new method called getChoice(). The return type is
a string. This string is used in the switch statement in Main(). The method name
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
"getChoice" describes what happens when it is invoked. Since the parenthesis are empty,
no information will be transferred to or from the getChoice() method.

Within the method block we first declare the variable myChoice. Although this is the
same name and type as the myChoice variable in Main(), they are both unique variables.
They are local variables and they are visible only in the block they are declared. In other
words, the myChoice in getChoice() knows nothing about the existence of the myChoice
in Main(), and vice versa.

The getChoice() method prints a menu to the console and gets the user's input. The return
statement sends the data from the myChoice variable back to the caller, Main(), of

Page 105
C# Programming And .Net Framework

getChoice(). Notice that the type returned by the return statement must be the same as the
return-type in the function declaration. In this case it is a string.

In the Main() method we must instantiate a new OneMethod object before we can use
getChoice(). This is because of the way getChoice() is declared. Since we did not specify
a static modifier, as for Main(), getChoice() becomes an instance method. The difference
between instance methods and static methods is that multiple instances of a class can be
created (or instantiated) and each instance has its own separate getChoice() method.
However, when a method is static, there are no instances of that method, and you can
invoke only that one definition of the static method.

So, as stated, getChoice() is not static and therefore, we must instantiate a new object to
use it. This is done with the declaration OneMethod om = new OneMethod(). On the left
hand side of the declaration is the object reference om which is of type OneMethod. The
distinction of om being a reference is important. It is not an object itself, but it is a
variable that can refer (or point ) to an object of type OneMethod. On the right hand side
of the declaration is an assignment of a new OneMethod object to the reference om. The
keyword new is a C# operator that creates a new instance of an object on the heap. What
is happening here is that a new OneMethod instance is being created on the heap and then
being assigned to the om reference. Now that we have an instance of the OneMethod
object referenced by om, we can manipulate that instance through the om reference.

Methods, fields, and other class members can be accessed, identified, or manipulated
through the "." (dot) operator. Since we want to call getChoice(), we do so by using the
dot operator through the om reference: om.getChoice(). The program then executes the
statements in the getChoice() block and returns. To capture the value getChoice()
returns, we use the "=" (assignment) operator. The returned string is placed into Main()'s
local myChoice variable.

Program 4-2. Method Parameters: MethodParams.cs

using System;

class Address
{
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
public string name;
public string address;
}

class MethodParams
{
public static void Main()
{
string myChoice;

MethodParams mp = new MethodParams();

Page 106
C# Programming And .Net Framework

do
{
// show menu and get input from user
myChoice = mp.getChoice();

// Make a decision based on the user's choice


mp.makeDecision(myChoice);

// Pause to allow the user to see the results


Console.Write("press Enter key to continue...");
Console.ReadLine();
Console.WriteLine();
} while (myChoice != "Q" && myChoice != "q"); // Keep going until the user wants
to quit
}

// show menu and get user's choice


string getChoice()
{
string myChoice;

// Print A Menu
Console.WriteLine("My Address Book\n");

Console.WriteLine("A - Add New Address");


Console.WriteLine("D - Delete Address");
Console.WriteLine("M - Modify Address");
Console.WriteLine("V - View Addresses");
Console.WriteLine("Q - Quit\n");

Console.WriteLine("Choice (A,D,M,V,or Q): ");

// Retrieve the user's choice


myChoice = Console.ReadLine();

}
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
return myChoice;

// make decision
void makeDecision(string myChoice)
{
Address addr = new Address();

switch(myChoice)
{
case "A":

Page 107
C# Programming And .Net Framework

case "a":
addr.name = "Joe";
addr.address = "C# Station";
this.addAddress(ref addr);
break;
case "D":
case "d":
addr.name = "Robert";
this.deleteAddress(addr.name);
break;
case "M":
case "m":
addr.name = "Matt";
this.modifyAddress(out addr);
Console.WriteLine("Name is now {0}.", addr.name);
break;
case "V":
case "v":
this.viewAddresses("Cheryl", "Joe", "Matt", "Robert");
break;
case "Q":
case "q":
Console.WriteLine("Bye.");
break;
default:
Console.WriteLine("{0} is not a valid choice", myChoice);
break;
}
}

// insert an address
void addAddress(ref Address addr)
{
Console.WriteLine("Name: {0}, Address: {1} added.", addr.name, addr.address);
}
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
// remove an address
void deleteAddress(string name)
{
Console.WriteLine("You wish to delete {0}'s address.", name);
}

// change an address
void modifyAddress(out Address addr)
{
//Console.WriteLine("Name: {0}.", addr.name); // causes error!

Page 108
C# Programming And .Net Framework

addr = new Address();


addr.name = "Joe";
addr.address = "C# Station";
}

// show addresses
void viewAddresses(params string[] names)
{
foreach (string name in names)
{
Console.WriteLine("Name: {0}", name);
}
}
}

Program 4-2 is a modification of Program 4-1, modularizing the program and adding
more implementation to show parameter passing. There are 4 kinds of parameters a C#
method can handle: out, ref, params, and value. To help illustrate usage of parameters,
we created an Address class with two string fields.

In Main() we call getChoice() to get the user's input and put that string in the myChoice
variable. Then we use myChoice as an argument to makeDecision(). In the declaration of
makeDecision() you'll notice its one parameter is declared as a string with the name
myChoice. Again, this is a new myChoice, separate from the caller's argument and local
only to this method. Since makeDecision()'s myChoice parameter does not have any
other modifiers, it is considered a value parameter. The actual value of the argument is
copied on the stack. Variables given by value parameters are local and any changes to
that local variable do not affect the value of the variable used in the caller's argument.

The switch statement in makeDecision() calls a method for each case. These method calls
are different from the ones we used in Main(). Instead of using the mp reference, they use
the this keyword. this is a reference to the current object. We know the current object has
been instantiated because makeDecision() is not a static method. Therefore, we can use
the this reference to call methods within the same instance.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
The addAddress() method takes a ref parameter. This means that a reference to the
parameter is copied to the method. This reference still refers to the same object on the
heap as the original reference used in the caller's argument. This means any changes to
the local reference's object also changes the caller reference's object. The code can't
change the reference, but it can make changes to the object being referenced. You can
think of this as a way to have an input/output parameter.

out parameters are for those parameters that are only returned from a method. This is
more efficient because the program doesn't have the overhead of copying the parameter
in to the method. On a normal program, this overhead is minimal. However, in distributed

Page 109
C# Programming And .Net Framework

processing scenarios, where network communication is the bottleneck, out parameters


make a larger difference.

modifyAddress() has an out parameter. out parameters are only passed back to the calling
function. Because of definite assignment rules, you cannot use this variable until it has a
valid value assigned. The first line in modifyAddress() is commented on purpose to
illustrate this point. Uncomment it and compile to see what happens. Once assigned and
the program returns, the value of the out parameter will be copied into the caller's
argument variable. You must assign a value to an out parameter before your method
returns.

A very useful addition to the C# language is the params parameter, which lets you define
a method that can accept a variable number of arguments. The params parameter must be
a single dimension or jagged array. In makeDecision() we pass in four comma delimited
string arguments. The number of arguments is variable. In viewAddresses() we use a
foreach loop to print each of these strings. Instead of the comma delimited list, the input
could have also been a string array. The params parameter is considered an input only
parameter and any changes affect the local copy only.

4.2.3 Namespaces

Namespaces are C# program elements designed to help you organize your programs.
They also provide assistance in avoiding name clashes between two sets of code.
Implementing Namespaces in your own code is a good habit because it is likely to save
you from problems later when you want to reuse some of your code.

Namespaces don't correspond to file or directory names. If naming directories and files to
correspond to namespaces helps you organize your code, then you may do so, but it is not
required.

Program 4-1. The C# Station Namespace: NamespaceCSS.cs

// Namespace Declaration
using System;
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
// The C# Station Namespace
namespace csharp_station
{
// Program start class
class NamespaceCSS
{
// Main begins program execution.
public static void Main()
{
// Write to console

Page 110
C# Programming And .Net Framework

Console.WriteLine("This is the new C# Station Namespace.");


}
}
}

Program 4-1 shows how to create a namespace. We declare the new namespace by
putting the word namespace in front of csharp_station. Curly braces surround the
members inside the csharp_station namespace.

Program 4-2. Nested Namespace 1: NestedNamespace1.cs

// Namespace Declaration
using System;

// The C# Station Namespace


namespace csharp_station
{
namespace {
// Program start class
class NamespaceCSS
{
// Main begins program execution.
public static void Main()
{
// Write to console
Console.WriteLine("This is the new C# Station Namespace.");
}
}
}
}

Namespaces allow you to create a system to organize your code. A good way to organize
your namespaces is via a hierarchical system. You put the more general names at the top
of the hierarchy and get more specific as you go down. This hierarchical system can be
represented by nested namespaces. Program 4-2 shows how to create a nested
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
namespace. By placing code in different sub-namespaces, you can keep your code
organized.

Program 4-3. Nested Namespace 2: NestedNamespace2.cs

// Namespace Declaration
using System;

// The C# Station Namespace


namespace csharp_station
{

Page 111
C# Programming And .Net Framework

// Program start class


class NamespaceCSS
{
// Main begins program execution.
public static void Main()
{
// Write to console
Console.WriteLine("This is the new C# Station Sample Namespace.");
}
}
}

Program 4-3 shows another way of writing nested namespaces. It specifies the nested
namespace with the dot operator between csharp_station. The result is exactly the same
as Program 4-2. However, Program 4-3 is easier to write.

Program 4-4. Calling Namespace Members: NamespaceCall.cs

// Namespace Declaration
using System;

namespace csharp_station
{
// nested namespace
namespace a {
class myExample1
{
public static void myPrint1()
{
Console.WriteLine("First Example of calling another namespace member.");
}
}
}
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
// Program start class
class NamespaceCalling
{
// Main begins program execution.
public static void Main()
{
// Write to console
a.myExample1.myPrint1();
a.myExample2.myPrint2();
}

Page 112
C# Programming And .Net Framework

}
}

// same namespace as nested namespace above


namespace csharp_station.a
{
class myExample2
{
public static void myPrint2()
{
Console.WriteLine("Second Example of calling another namespace member.");
}
}
}

Program 4-4 provides an example of how to call namespace members with fully qualified
names. A fully qualified name contains every language element from the namespace
name down to the method call. At the top of the Program there is a nested namespace a
within the csharp-station namespace with class myExample1 and method myPrint1.
Main() calls this method with the fully qualified name of a .myExample1.myPrint().
Since Main() and the a namespace are located in the same namespace, using
csharp_station in the fully qualified name is unnecessary.

At the bottom of Program 4-4 is an addition to the csharp_station.a namespace. The


classes myExample1 and myExample2 both belong to the same namespace. Additionally,
they could be written in separate files and still belong to the same namespace. In Main(),
the myPrint2() method is called with the fully qualified name a.myExample2.myPrint2().
Although the class myExample2 is outside the bounding braces of where the method
myPrint2 is called, the namespace csharp_station does not need to be a part of the fully
qualified name. This is because both classes belong to the same namespace,
csharp_station.

Notice that I used different names for the two classes myExample1 and myExample2.
This was necessary because every namespace member of the same type must have a
unique name. Remember, they are both in the same namespace and you wouldn't want
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
any ambiguity about which class to use. The methods myPrint1() and myPrint2() have
different names only because it would make the lesson a little easier to follow. They
could have had the same name with no effect, because their classes are different, thus
avoiding any ambiguity.

Program 4-5. The using Directive: UsingDirective.cs

// Namespace Declaration
using System;
using csharp_station.sample;

Page 113
C# Programming And .Net Framework

// Program start class


class UsingDirective
{
// Main begins program execution.
public static void Main()
{
// Call namespace member
myExample.myPrint();
}
}

// C# Station Sample Namespace


namespace csharp_station.sample
{
class myExample
{
public static void myPrint()
{
Console.WriteLine("Example of using a using directive.");
}
}
}

If you would like to call methods without typing their fully qualified name, you can
implement the using directive. In Program 4-5, we show two using directives. The first,
using System, is the same using directive you have seen in every program in this sample.
It allows you to type the method names of members of the System namespace without
typing the word System every time. In myPrint(), Console is a class member of the
System namespace with the method WriteLine(). Its fully qualified name is
System.Console.WriteLine(...).

Similarly, the using directive using csharp_station.sample allows us to implement


members of the csharp_station.sample namespace without typing the fully qualified
name. This is why we can type myExample.myPrint(). Without the using directive, we
would have to type csharp_station.sample.myExample.myPrint() every time we wanted
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
to implement that method.

Program 4-6. The Alias Directive: AliasDirective.cs

// Namespace Declaration
using System;
using csTut = csharp_station.sample.myExample; // alias

// Program start class


class AliasDirective
{

Page 114
C# Programming And .Net Framework

// Main begins program execution.


public static void Main()
{
// Call namespace member
csTut.myPrint();
myPrint();
}

// Potentially ambiguous method.


static void myPrint()
{
Console.WriteLine("Not a member of csharp_station.sample.myExample.");
}
}

// C# Station Sample Namespace


namespace csharp_station.sample
{
class myExample
{
public static void myPrint()
{
Console.WriteLine("This is a member of csharp_station.sample.myExample.");
}
}
}

Sometimes you may encounter a long namespace and wish to have it shorter. This could
improve readability and still avoid name clashes with similarly named methods. Program
4-6 shows how to create an alias with the alias directive using csTut =
csharp_station.sample.myExample. Now the expression csTut can be used anywhere, in
this file, in place of csharp_station.sample.myExample. We use it in Main().

Also in Main() is a call to the myPrint() method of the AliasDirective class. This is the
same name as the myPrint() method in the myExample class . The reason both of these
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
methods can be called in the same method call is because the myPrint() method in the
myExample class is qualified with the csTut alias. This lets the compiler know exactly
which method is to be executed. Had we mistakenly omitted csTut from the method call,
the compiler would have set up the myPrint() method of the AliasDirective class to run
twice.

4.2.4 Structs

A struct allows you to create new value-type objects that are similar to the built-in types
(int, float, bool, etc.). When would you use a struct instead of a class? Think about how
the built-in types are used. They have values and distinct operations to manipulate those

Page 115
C# Programming And .Net Framework

values. If you have a need to create an object that behaves in this manner, consider
implementing it as a struct. Later in this article, I'll explain a couple rules for using
structs, which will give you a better idea of when to use them. In the meantime, here's an
example.

Program 4-1. Example of a struct: StructExample.cs

using System;

struct Point
{
public int x;
public int y;

public Point(int x, int y)


{
this.x = x;
this.y = y;
}

public Point Add(Point pt)


{
Point newPt;

newPt.x = x + pt.x;
newPt.y = y + pt.y;

return newPt;
}
}

/// <summary>
/// Example of declaring and using a struct
/// </summary>
class StructExample
{ ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
static void Main(string[] args)
{
Point pt1 = new Point(1, 1);
Point pt2 = new Point(2, 2);
Point pt3;

pt3 = pt1.Add(pt2);

Console.WriteLine("pt3: {0}:{1}", pt3.x, pt3.y);

Page 116
C# Programming And .Net Framework

}
}

Program 4-1 shows how to declare and use a struct. It is easy to tell that a type is a struct
because of the keywordstruct used in its definition. The basic layout of a struct is much
like a class, but with differences, which will be explained in following paragraphs. The
Point struct has a constructor which initializes its fields to the x and y values passed in. It
also has a method named Add(), which will accept another Point struct, add it to this
struct, and return a new struct.

Notice that there is a Point struct declared in the Add() method. It does not need to be
instantiated with a new operator, like a class. When this occurs, the struct is implicitly
instantiated with its default (or parameterless) constructor. The parameterless constructor
initializes all struct fields to default values. i.e. integrals are 0, floating points are 0.0, and
booleans are false. It's illegal to define a parameterless constructor for a struct.

Although not required, a struct may be instantiated with a new operator. In Program 12-1
the pt1 and pt2 Point structs are initialized with values by using the constructor defined in
the Point struct. A third Point struct, pt3 is declared and defaults to using the
parameterless (default) constructor, because it doesn't matter what it's value is at this
point. The Add() method of the pt1 struct is then invoked, passing the pt2 struct as a
parameter. The result is assigned to pt3, showing that a struct may be used just like any
other value type. Here's the output from Program

pt3: 3:3

Another difference between structs and classes is that structs can not have destructors.
Also, structs cannot inherit another class or struct or be inherited from. However, a struct
may inherit multiple interfaces. An interface is a C# reference type with members that do
not have implementations. Any class or struct inheriting an interface must implement
every one of that interface's methods. Interfaces are a subject for a later lesson.

In summary, you now know how to create a struct. You can also instantiate and use
structs. When deciding whether to implement a type as a struct or class, you should
consider how the type will be used. If you need to define a parameterless constructor,
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
then a class is your only choice. Also, consider that a struct incurs less overhead than a
class because, being a value type, it is stored on the stack rather than how a class is
stored, on the heap.

4.2.5 Introduction to Exception Handling

Exceptions

Exceptions are unforeseen errors that happen in your programs. Most of the time, you
can, and should, detect and handle program errors in your code. For example, validating
user input, checking for null objects, and verifying the values returned from methods are

Page 117
C# Programming And .Net Framework

what you expect, are all examples of good standard error handling that you should be
doing all the time.

However, there are times when you don't know if an error will occur. For example, you
can't predict when you'll receive a file I/O error, run out of system memory, or encounter
a database error. These things are generally unlikely, but they could still happen and you
want to be able to deal with them when they do occur. This is where exception handling
comes in.

When exceptions occur, they are said to be "thrown". What is actually thrown is an object
that is derived from the System.Exception class. In the next section, I'll be explaining how
thrown exceptions are handled with try/catch blocks.

The System.Exception class provides several methods and properties for obtaining
information on what went wrong. For example, the Message property provides summary
information about what the error was, the Stacktrace property provides information from
the stack for where the problem occurred, and the ToString() method is overridden to
reveal a verbose description of the entire exception.

Identifying the exceptions you'll need to handle depends on the routine you're writing.
For example, if the routine opened a file with the System.IO.File.OpenRead() method, it
could throw any of the following exceptions:

 SecurityException
 ArgumentException
 ArgumentNullException
 PathTooLongException
 DirectoryNotFoundException
 UnauthorizedAccessException
 FileNotFoundException
 NotSupportedException

It's easy to find out what exceptions a method can raise by looking in the .NET
Frameworks SDK Documentation. Just go to the Reference/Class Library section and
look in the Namespace/Class/Method documentation for the methods you use. The
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
exception in the list above were found by looking at the OpenRead() method definition of
the File class in the System.IO namespace. Each exception identified has a hyperlink to
its class definition that you can use to find out what that exception is about. Once you've
figured out what exceptions can be generated in your code, you need to put the
mechanisms in place to handle the exceptions, should they occur.

try/catch Blocks

When exceptions are thrown, you need to be able to handle them. This is done by
implementing a try/catch block. Code that could throw an exception is put in the try
block an exception handling code goes in the catch block. Program 15-1 shows how to

Page 118
C# Programming And .Net Framework

implement a try/catch block. Since an OpenRead() method could throw one of several
exceptions, it is placed in the try block. If an exception is thrown, it will be caught in the
catch block. The code in Program 15-1 will print message and stack trace information out
to the console if an exception is raised.

Note: The programs in this lesson cause exceptions on purpose. The exception that you
see is generated intentionally to show you what the exception message looks like before
you see it yourself in your own programs.

Program 4-1. Using try/catch Blocks: tryCatchDemo.cs

using System;
using System.IO;

class tryCatchDemo
{
static void Main(string[] args)
{
try
{
File.OpenRead("NonExistentFile");
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}

Although the code in Program 15-1 only has a single catch block, all exceptions will be
caught there because the type is of the base exception type "Exception". In exception
handling, more specific exceptions will be caught before their more general parent
exceptions. For example, the following snippet shows how to place multiple catch blocks:

catch(FileNotFoundException fnfex)
{ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Console.WriteLine(fnfex.ToString());
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}

If the file doesn't exist, a FileNotFoundException exception will be thrown and caught by
the first catch block. However, if a PathTooLongException exception was raised, the
second catch part would catch the exception. This is because there isn't a catch block for

Page 119
C# Programming And .Net Framework

the PathTooLongException exception and the generic Exception type catch block is the
only option available to catch the exception.

Exceptions that are not handled will normally bubble up the stack until a calling routine
in the call chain handles them. If you forget to include try/catch blocks in a part of your
code and there aren't any try/catch blocks earlier in the call chain, your program will
abort with a message describing the exception. To your users this would be very cryptic
and uncomfortable. It is good practice to provide exception handling in your programs.

Finally Blocks

An exception can leave your program in an inconsistent state by not releasing resources
or doing some other type of cleanup. A catch block is a good place to figure out what
may have went wrong and try to recover, however it can't account for all scenarios.
Sometimes you need to perform clean up actions whether or not your program succeeds.
These situations are good candidates for using a finally block.

Program 4-2 illustrates the usefulness of a finally block. As you know, a file stream must
be closed when your done with it. In this case, the file stream is the resource that needs to
be cleaned up. In Program 15-2, outStream is opened successfully, meaning the program
now has a handle to an open file resource. When trying to open the inStream, a
FileNotFoundException exception is raised, causing control to go immediately to the
catch block.

It's possible to close the outStream in the catch block, but what if the algorithm executed
successfully without an exception? On success, the file would never be closed.
Fortunately, we've included a finally block in Program 15-2, which will always be
executed. That's right, regardless of whether the algorithm in the try block raises an
exception or not, the code in the finally block will be executed before control leaves the
method.

Program 4-2. Implementing a finally Block: FinallyDemo.cs

using System;
using System.IO;
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
class FinallyDemo
{
static void Main(string[] args)
{
FileStream outStream = null;
FileStream inStream = null;

try
{
outStream = File.OpenWrite("DestinationFile.txt");

Page 120
C# Programming And .Net Framework

inStream = File.OpenRead("BogusInputFile.txt");
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
if (outStream != null)
{
outStream.Close();
Console.WriteLine("outStream closed.");
}
if (inStream != null)
{
inStream.Close();
Console.WriteLine("inStream closed.");
}
}
}
}

A finally block is not required and you may ask what happens if you just put code after
the catch block. true, under normal circumstances, if the exception is caught, all code
following the catch will be executed. However, try/catch/finally is for exceptional
circumstances and it is better to plan for the worst to make your program more robust.
For example, if one of the catch handlers re threw and exception or caused another
exception, the code following the catch block (not in a finally block) would never be
executed. Also, if you don't catch the exception at all, program flow would immediately
do a stack walk looking for an exception handler that fits and the code following the
catch blocks would not be executed. Since there is too much potential for code in an
algorithm to not be executed, a finally block is your insurance for executing those critical
actions you need.

This has been an introduction to handling exceptions. By now, you should have a good
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
understanding of what an exception is. You can implement algorithms within try/catch
blocks that handle exceptions. Additionally, you know how to clean up resources by
implementing a finally block whose code is always executed before leaving a method.

4.2.6 Enums Defined

Enums are strongly typed constants. They are essentially unique types that allow you to
assign symbolic names to integral values. In the C# tradition, they are strongly typed,
meaning that an enum of one type may not be implicitly assigned to an enum of another
type even though the underlying value of their members are the same. Along the same

Page 121
C# Programming And .Net Framework

lines, integral types and enums are not implicitly interchangable. All assignments
between different enum types and integral types require an explicit cast.

Enums lend themselves to more maintainable code because they are symbolic, allowing
you to work with integral values, but using a meaningful name to do so. For example,
what type of code would you rather work with - a set of values named North, South, East,
and West or the set of integers 0, 1, 2, and 3 that mapped to the same values, respectively.
Enums make working with strongly typed constants via symbolic names easy.

Enums are value types, which means they contain their own value, can't inherit or be
inherited from, and assignment copies the value of one enum to another. You will see in
this lesson and elsewhere that enums are used and referred to with both lower case, enum,
and upper case, Enum. Strangely enough, the relationship between the two is that the C#
type, enum, inherits the Base Class Library (BCL) type, Enum.Use the C# type, enum, to
define new enums and use the BCL type, Enum, to implement static enum methods.

Creating an Enum

The .NET Framework BCL contains many enums and examples of how they are used.
For example, every time you put an icon on a MessageBox, you use the MessageBoxIcons
enum. For a list of available enums in the BCL, look at the documentation for the Enum
class and click on the Derived Classes link.

Whenever there are situations where you are using a set of related numbers in a program,
consider replacing those numbers with enums. It will make a program more readable and
type safe. Program 17-1 contains an enum definition and code that uses that enum in a
switch statement. Instead of using the numbers 0, 1, and 2 in the switch statement, the
code is more meaningful through the use of the Volume enum.

Program 4-1. Creating and Using an Enum: EnumSwitch.cs

using System;

// declares the enum


public enum Volume
{ ANNAMALAI
ANNAMALAI UNIVERSITY
Low,
UNIVERSITY
Medium,
High
}

// demonstrates how to use the enum

class EnumSwitch
{
static void Main()

Page 122
C# Programming And .Net Framework

{
// create and initialize
// instance of enum type
Volume myVolume = Volume.Medium;

// make decision based


// on enum value
switch (myVolume)
{
case Volume.Low:
Console.WriteLine("The volume has been turned Down.");
break;
case Volume.Medium:
Console.WriteLine("The volume is in the middle.");
break;
case Volume.High:
Console.WriteLine("The volume has been turned up.");
break;
}
Console.ReadLine();
}
}

Program 4-1 contains a definition for an enum. Notice that it is declared with the enum
keyword, has a type identifier (Volume), and contains a comma separated list of values
enclosed within curly braces.

This enum is of type Volume and we use it to declare the myVolume variable in the Main
method. Since an enum is a value type, we can assign a value (Volume.Medium) to it
directly, similar to the simple types such as int or double. Once the myVolume variable is
declared and initialized, it is used in the switch statement.Each of the case statements
represent a unique member of the Volume enum.

Any time a member of the Volume enum is used, it is fully qualified with the "Volume"
identifier to guarantee type safety. For example, if there were a Meat enum in scope, then
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Meat.Medium would definitely have different semantics than Volume.Medium. With both
enums in scope, it would be ambiguous to just use the Medium identifier without type
qualification. Using the type identifier ensures such mistakes are not made.

Using Enums

An enum is typically specified as shown in Program 17-1, but may be customized by


changing its base type and member values. By default, the underlying type of of an enum
is int.This default may be changed by specifying a specific base when declaring the
enum. You would specify a different base if the enum was used extensively and there was
an opportunity for space savings by selecting a smaller type. Another reason may be if

Page 123
C# Programming And .Net Framework

you wanted the underlying type of the enum to correspond to another type in your
program and you wanted to explicitly cast between the two without loss of precision.
Valid base types include byte, sbyte, short, ushort, int, uint, long, and ulong.

Another modification you can make to an enum is to set the value of any enum member.
By default, the first member of an enum takes the value of zero. If this value doesn't
make sense for your enum, you can change it to one or some other number.Additionally,
you can change any of the members of an enum to any value that is valid for its base
type.Unassigned enum members have a value that is one more than their predecessor.
Program 4-2 shows how to modify the base type and member values of an enum.

Program 4-2. Setting the Enum Base and Initializing Members:


EnumBaseAndMembers.cs

using System;

// declares the enum


public enum Volume : byte
{
Low = 1,
Medium,
High
}

class EnumBaseAndMembers
{
static void Main()
{
// create and initialize
// instance of enum type
Volume myVolume = Volume.Low;

// make decision based


// on enum value
switch (myVolume)
{ ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
case Volume.Low:
Console.WriteLine("The volume has been turned Down.");
break;
case Volume.Medium:
Console.WriteLine("The volume is in the middle.");
break;
case Volume.High:
Console.WriteLine("The volume has been turned up.");
break;
}

Page 124
C# Programming And .Net Framework

Console.ReadLine();
}
}

The Volume enum in Program 4-2 shows how to modify the base type and members of an
enum.Its base type is changed to byte with the : <type> syntax following the enum
identifier, Volume.This ensures that the Volume enum may only have members with
values that are valid for type byte.

The first member of the Volume enum, Low, has its value changed to 1.The same syntax,
<member> = <value>, may be applied to any member of the enum.You are restricted
from creating forward references, circular references, and duplicate references in enum
members.

The default values of the Volume enum are Low=0, Medium=1, and High=2 because the
first member of an enum defaults to 0 and the following members default to one more
than their predecessor.However, the Volume enum in Program 17-2 has its Low member
set to 1, which means that Medium=2 and High=3.

Enum tricks

Enum types implicitly inherit the System.Enum type in the Base Class Library (BCL).
This also means that you can use the members of System.Enum to operate on enum
types. This section does just that, showing some useful tips and tricks to use with enums
in your programs.

A common requirement with enums is to convert between the enum and a variable of its
base type. For example, if you are getting input in the form of an int from a user or a file
stream, then you can cast it to an enum and use it in a meaningful way in your
program.You can also get a complete list of enum member names or enum values, which
is useful if you have logic that needs to iterate through every enum member. Program 17-
3 shows how to perform conversions between enums and their base types and how to use
some of the System.Enum type members.

Program 4-3. Enum Conversions and using the System.Enum Type: Enumtricks.cs
ANNAMALAI
ANNAMALAI UNIVERSITY
using System;
UNIVERSITY
// declares the enum
public enum Volume : byte
{
Low = 1,
Medium,
High
}

Page 125
C# Programming And .Net Framework

// shows different ways


// to work with enums
class Enumtricks
{
static void Main(string[] args)
{
// instantiate type
Enumtricks enumtricks = new Enumtricks();

// demonstrates explicit cast


// of int to Volume
enumtricks.GetEnumFromUser();

// iterate through Volume enum by name


enumtricks.ListEnumMembersByName();

// iterate through Volume enum by value


enumtricks.ListEnumMembersByValue();

Console.ReadLine();
}

// demonstrates explicit cast


// of int to Volume
public void GetEnumFromUser()
{
Console.WriteLine("\n----------------");
Console.WriteLine("Volume Settings:");
Console.WriteLine("----------------\n");

Console.Write(@"
1 - Low
2 - Medium
3 - High

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Please select one (1, 2, or 3): ");

// get value user provided


string volString = Console.ReadLine();
int volInt = Int32.Parse(volString);

// perform explicit cast from


// int to Volume enum type
Volume myVolume = (Volume)volInt;

Console.WriteLine();

Page 126
C# Programming And .Net Framework

// make decision based


// on enum value
switch (myVolume)
{
case Volume.Low:
Console.WriteLine("The volume has been turned Down.");
break;
case Volume.Medium:
Console.WriteLine("The volume is in the middle.");
break;
case Volume.High:
Console.WriteLine("The volume has been turned up.");
break;
}

Console.WriteLine();
}

// iterate through Volume enum by name


public void ListEnumMembersByName()
{
Console.WriteLine("\n---------------------------- ");
Console.WriteLine("Volume Enum Members by Name:");
Console.WriteLine("----------------------------\n");

// get a list of member names from Volume enum,


// figure out the numeric value, and display
foreach (string volume in Enum.GetNames(typeof(Volume)))
{
Console.WriteLine("Volume Member: {0}\n Value: {1}",
volume, (byte)Enum.Parse(typeof(Volume), volume));
}
}

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
// iterate through Volume enum by value
public void ListEnumMembersByValue()
{
Console.WriteLine("\n----------------------------- ");
Console.WriteLine("Volume Enum Members by Value:");
Console.WriteLine("-----------------------------\n");

// get all values (numeric values) from the Volume


// enum type, figure out member name, and display
foreach (byte val in Enum.GetValues(typeof(Volume)))
{

Page 127
C# Programming And .Net Framework

Console.WriteLine("Volume Value: {0}\n Member: {1}",


val, Enum.GetName(typeof(Volume), val));
}
}
}

The code in Program 4-3 includes three method calls to GetEnumFromUser,


ListEnumMembersByName, and ListEnumMembersByValue. Each of these methods
demonstrate a different aspect of using System.Enum to work with enums.

The GetEnumFromUser method shows how to obtain int input and translate it to an
appropriate enum type.Converting an int to an enum makes the code more readable and
type safe.The following is an excerpt from Program 4-3 that shows the pertinent part of
the code that performs the conversion:

// get value user provided


string volString = Console.ReadLine();
int volInt = Int32.Parse(volString);

// perform explicit cast from


// int to Volume enum type
Volume myVolume = (Volume)volInt;

After the program displays a menu, it prompts the user for a selection in the form of a
number (1, 2, or 3). When the user makes a selection and presses the Enter key, the code
reads the value with Console.ReadLine, which returns the value as a string type. Since
you can only cast an int to a Volume enum type, the user's input must be converted from a
string to an int with the Int32.Parse method. Converting the int to a Volume enum type is
simply a matter of applying a cast operation during assignment.

To get all the members of an enum at the same time, you can use the GetNames method
of the System.Enum type, which returns a string array of the names of all an enum's
members. An exerpt from the ListEnumMembersByName method in Program 17.3 that
shows this appears below:

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
// get a list of member names from Volume enum,
// figure out the numeric value, and display
foreach (string volume in Enum.GetNames(typeof(Volume)))
{
Console.WriteLine("Volume Member: {0}\n Value: {1}",
volume, (byte)Enum.Parse(typeof(Volume), volume));
}

Because GetNames returns an array of strings, it is easy to use in a loop statement such as
foreach. Something you may be curious about in the code above is the second parameter
to the WriteLine method's format string. Given the enum type and a string representation

Page 128
C# Programming And .Net Framework

of the member name, you can use the Enum.Parse method to get the underlying value of
that member. Because the Volume enum's base type is byte, the return value from
Enum.Parse must be cast to a byte before assignment, forcing the numeric representation
of the enum value to appear. If we would have omitted the byte cast, the output would be
the Volume enum member, which would then be converted to a string representation of
the member name, which is not what the code intended to show.

Instead of getting names of all the members of an enum, you may have a reason to get all
the values of the enum at one time. The code below, from the ListEnumMembersByValue
method in Program 4.3, shows how to accomplish this:

// get all values (numeric values) from the Volume


// enum type, figure out member name, and display
foreach (byte val in Enum.GetValues(typeof(Volume)))
{
Console.WriteLine("Volume Value: {0}\n Member: {1}",
val, Enum.GetName(typeof(Volume), val));
}

Given the type of the enum, the GetValues method of System.Enum will return an array
of the given enum's base type, which in this case is byte.While iterating through this list,
each member is printed to the console showing its value and name. The name is obtained
by using the GetName method of System.Enum, which accepts an enum type and value
for which to get the corresponding name of.

4.2.7 Introduction to Classes

Classes are declared by using the keyword class followed by the class name and a set of
class members surrounded by curly braces. Every class has a constructor, which is called
automatically any time an instance of a class is created. The purpose of constructors is to
initialize class members when the class is created. Constructors do not have return values
and always have the same name as the class. Program 7-1 is an example of a class.

Program 4-1. Example C# Classes: Classes.cs

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
// Namespace Declaration
using System;

// helper class
class OutputClass
{
string myString;

// Constructor
public OutputClass(string inputString)
{

Page 129
C# Programming And .Net Framework

myString = inputString;
}

// Instance Method
public void printString()
{
Console.WriteLine("{0}", myString);
}

// Destructor
~OutputClass()
{
// Some resource cleanup routines
}
}

// Program start class


class ExampleClass
{
// Main begins program execution.
public static void Main()
{
// Instance of OutputClass
OutputClass outCl = new OutputClass("This is printed by the output class.");

// Call Output class' method


outCl.printString();
}
}

Program 4-1 shows two classes. The top class, OutputClass, has a constructor, instance
method, and a destructor. It also had a field named myString. Notice how the OutputClass
constructor is used to initialize data members of the class. In this case, the OutputClass
constructor accepts a string argument, inputString. This string is copied to the class field
myString.ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Constructors are not mandatory, as indicated by the implementation of ExampleClass. In
this case, a default constructor is provided. A default constructor is simply a constructor
with no arguments. However, a constructor with no arguments is not always useful. To
make default constructors more useful, you can implement them with initializers. Here is
an example:

Page 130
C# Programming And .Net Framework

public OutputClass() : this("Default Constructor String") { }

Imagine this constructor was included in class OutputClass from Program 4-1. This
default constructor is followed by an initializer. The colon, ":", marks the beginning of
the initializer, followed by the this keyword. The this keyword refers to this particular
object. It effectively makes a call to the constructor of the same object it is defined in.
After the this keyword is a parameter list with a string. The action taken by the initializer
above is to invoke the OutputClass constructor that takes a string type as an argument.
The initializer helps you to ensure your class fields are initialized when a class is
instantiated.

The example above illustrates how a class can have multiple constructors. The specific
constructor called depends on the number of parameters and the type of each parameter.

In C#, there are two types of class members, instance and static. Instance class members
belong to a specific occurrence of a class. Every time you declare an object of a certain
class, you create a new instance of that class. The ExampleClass Main() method creates
an instance of the OutputClass named outCl. You can create multiple instances of
OutputClass with different names. Each of these instances are separate and stand alone.
For example, if you create two OutputClass instances as follows:

OutputClass oc1 = new OutputClass("OutputClass1");


OutputClass oc2 = new OutputClass("OutputClass2");

You create two separate instances of OutputClass with separate myString fields and
separate printString() methods. On the other hand, if a class member is static, you can
access it simply by using the syntax <classname>.<static class member>. The instance
names are oc1 and oc2.

Suppose OutputClass had the following static method:

public static void staticPrinter()


{
Console.WriteLine("There is only one of me.");
}
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Then you could call that function from Main() like this:

OutputClass.staticPrinter();

You must call static class members through their class name and not their instance name.
This means that you don't need to instantiate a class to use its static members. There is
only ever one copy of a static class member. A good use of static members is when there
is a function to be performed and no intermediate state is required, such as math
calculations. Matter of fact, the .NET Frameworks Base Class Library includes a Math
class that makes extensive use of static members.

Page 131
C# Programming And .Net Framework

Another type of constructor is the static constructor. Use static constructor to initialize
static fields in a class. You declare a static constructor by using the keyword static just in
front of the constructor name. A static constructor is called before an instance of a class
is created, before a static member is called, and before the static constructor of a derived
class (covered in a later chapter). They are called only once.

OutputClass also has a destructor. Destructors look just like constructors, except they
have a tilde, "~", in front of them. They don't take any parameters and do not return a
value. Destructors are places where you could put code to release any resources your
class was holding during its lifetime. They are normally called when the C# garbage
collector decides to clean your object from memory.

So far, the only class members you've seen are Fields, Methods, Constructors, and
Destructors. Here is a complete list of the types of members you can have in your classes:

 Constructors
 Destructors
 Fields
 Methods
 Properties
 Indexers
 Delegates
 Events
 Nested Classes

4.2.8 Inheritance

As inheritance is used when a class is built upon another class—in terms of data or
behavior—and it adheres to the rules of substitutability—namely, that the derived class
can be substituted for the base class. An example of this would be if you were writing a
hierarchy of application classes,(let us say) you wanted to have a class for handling
memberA application and memberB application Assume these applications differ in some
respects, you'd want to have a class for each application. However, both applications do
share enough functionality that you would want to put common functionality into a base
class, derive the other two classes from the base class, and override or modify the
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
inherited base class behavior at times.
To inherit one class from another, you would use the following syntax:
class <derivedClass>: <baseClass>
Here is what this application example would look like:
using System;
class Application
{
public Application()
{
CommonField = 100;
}

Page 132
C# Programming And .Net Framework

public int CommonField;

public void CommonMethod()


{
Console.WriteLine("Application.Common Method");
}
}

class MemberA : Application


{
public void SomeMethodSpecificToMemberA()
{
Console.WriteLine("MemberA.SomeMethodSpecificToMemberA");
}
}

class MemberB : Application


{
public void SomeMethodSpecificToMemberB()
{
Console.WriteLine("MemberB.SomeMethodSpecificToMemberB");
}
}

class InheritanceApp
{
public static void Main()
{
MemberA memberA = new MemberA();

memberA.SomeMethodSpecificToMemberA();
memberA.CommonMethod();
Console.WriteLine("Inherited common field = {0}",
memberA.CommonField);

}
} ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Compiling and executing this application results in the following output:
MemberA.SomeMethodSpecificToMemberA
Application.Common Method
Inherited common field = 42
Notice that the Application.CommonMethod and Application.CommonField methods are
now a part of the MemberA class's definition. Because the MemberA and MemberB
classes are derived from the base Application class, they both inherit almost all of its
members that are defined as public, protected, or internal. The only exception to this is

Page 133
C# Programming And .Net Framework

the constructor, which cannot be inherited. Each class must implement its own
constructor irrespective of its base class.

4.2.9 Multiple Interfaces

C# does not support multiple inheritance through derivation. You can, however,
aggregate the behavioral characteristics of multiple programmatic entities by
implementing multiple interfaces. C# interfaces you would in a COM interface.
Having said that, the following program is invalid:
class Drivers
{
}

class Rast
{
}

class MITest : Drivers, Rast


{
public static void Main ()
{
}
}
The interfaces you choose to implement are listed after the class's base class.In this
example, the C# compiler thinks that Rast should be an interface type. That's why the C#
compiler will give you the following error message:
'Rast' : type in interface list is not an interface
The following, example is perfectly valid because the MyFancyGrid class is derived from
Control and implements the ISerializable and IDataBound interfaces:
class Control
{
}

interface ISerializable
{
} ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
interface IDataBound
{
}

class MyFancyGrid : Control, ISerializable, IDataBound


{
}
The highlight here is that the only way you can implement something like multiple
inheritance in C# is through the use of interfaces.

Page 134
C# Programming And .Net Framework

4.2.10 Sealed Classes

That a class can never be used as a base class, you use the sealed modifier when defining
the class. The only restriction is that an abstract class cannot be used as a sealed class
because by their nature abstract classes are meant to be used as base classes. Another
point to make is that although the purpose of a sealed class is to prevent unintended
derivation, certain run-time optimizations are enabled as a result of defining a class as
sealed. Specifically, because the compiler guarantees that the class can never have any
derived classes, it is possible to transform virtual function member invocations on sealed
class instances into nonvirtual invocations. Here's an example of sealing a class:
using System;
sealed class MyPinnacle
{
public MyPinnacle(int x,int y)
{
this.x =x;
this.y =y;
}

private int X;
public int x
{
get
{
return this.X;
}
set
{
this.X =value;
}
}

private int Y;
public int y
{ ANNAMALAI
ANNAMALAI UNIVERSITY
get
UNIVERSITY
{
return this.Y;
}
set
{
this.Y = value;
}
}
}

Page 135
C# Programming And .Net Framework

class SealedApp
{
public static void Main()
{
MyPinnacle pt = new MyPinnacle(6,16);
Console.WriteLine("x = {0}, y = {1}", pt.x, pt.y);
}
}
The private access modifier is used on the internal class members X and Y. Using the
protected modifier would result in a warning from the compiler because of the fact that
protected members are visible to derived classes and, as sealed classes don't have any
derived classes.

4.2.11 Polymorphism

Polymorphism enables you to define a method multiple times throughout your class
hierarchy in such a way that the runtime calls the appropriate version of that method
depending on the exact object being used.

Let us look at Staff example given below to understand the concept. The Pmorph1App
application runs correctly because we have two objects: a Staff object and a SalariedStaff
object. Probably we read all the Staff records from a database and populate an array.
Although some of these Staffs would be contractors and some would be salaried Staffs,
we would need to place them all in our array as the same type—the base class type, Staff.
However, when we iterate through this array, retrieving and calling each object's
ComputePay method, we would want the compiler to call the correct object's
implementation of the ComputePay method.

In the following example we have added a new class, ContractStaff. The main application
class now contains an array of type Staff and two additional methods—LoadStaffs loads
the Staff objects into the array, and DoPayroll iterates through the array, calling each
object's ComputePay method.
using System;

ANNAMALAI
ANNAMALAI UNIVERSITY
class Staff
{
UNIVERSITY
public Staff(string name)
{
this.Name = name;
}

protected string Name;

public string name


{

Page 136
C# Programming And .Net Framework

get
{
return this.Name;
}
}

public void ComputePay()


{
Console.WriteLine("Staff.ComputePay called for {0}",
name);
}
}

class ContractStaff : Staff


{
public ContractStaff(string name)
: base(name)
{
}

public new void ComputePay()


{
Console.WriteLine("ContractStaff.ComputePay called for {0}",
name);
}
}

class SalariedStaff : Staff


{
public SalariedStaff (string name)
: base(name)
{
}

public new void ComputePay()


{ ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Console.WriteLine("SalariedStaff.ComputePay called for {0}",
name);
}
}
class Pmorph2App
{
protected Staff[] Staffs;

public void LoadStaffs()


{

Page 137
C# Programming And .Net Framework

// Simulating loading from a database.


Staffs = new Staff[2];
Staffs[0] = new ContractStaff("Mike scott");
Staffs[1] = new SalariedStaff("Patrick");
}

public void DoPayroll()


{
foreach(Staff emp in Staffs)
{
emp.ComputePay();
}
}

public static void Main()


{
Pmorph2App Pmorph2 = new Pmorph2App();
Pmorph2.LoadStaffs();
Pmorph2.DoPayroll();
}
}

However, running this application results in the following output:


c:\>Pmorph2App
Staff.ComputePay called for Mike scott.
Staff.ComputePay called for Patrick.
Actually we did not expect this output. The base class's implementation of ComputePay
is being called for each object. When the code was compiled, the C# compiler looked at
the call to emp.ComputePay and determined the address in memory that it would need to
jump to when the call is made. In this case, that would be the memory location of the
Staff.ComputePay method.
That call to the Staff.ComputePay method creates the problem. What is expected instead
is for late binding to occur. Late binding means that the compiler does not select the
method to execute until run time. To force the compiler to call the correct version of an
upcasted object's method, we use two new keywords: virtual and override. The virtual
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
keyword must be used on the base class's method, and the override keyword is used on
the derived class's implementation of the method.
The following example the problem is solved and gives the expected output.

using System;

class Staff
{
public Staff(string name)
{
this.Name = name;

Page 138
C# Programming And .Net Framework

protected string Name;


public string name

{
get
{
return this.Name;
}
}

virtual public void ComputePay()


{
Console.WriteLine("Staff.ComputePay called for {0}",
name);
}
}

class ContractStaff : Staff


{
public ContractStaff(string name)
: base(name)
{
}
override public void ComputePay()
{
Console.WriteLine("ContractStaff.ComputePay called for {0}",
name);
}
}

class SalariedStaff : Staff


{
public SalariedStaff (string name)
ANNAMALAI
ANNAMALAI UNIVERSITY
: base(name)
{
UNIVERSITY
}
override public void ComputePay()
{
Console.WriteLine("SalariedStaff.ComputePay called for {0}",
name);
}
}

class Pmorph3App

Page 139
C# Programming And .Net Framework

{
protected Staff[] Staffs;
public void LoadStaffs()
{
// Simulating loading from a database.
Staffs = new Staff[2];

Staffs[0] = new ContractStaff("Mike scott");


Staffs[1] = new SalariedStaff("Patrick");
}

public void DoPayroll()


{
foreach(Staff emp in Staffs)
{
emp.ComputePay();
}
}

public static void Main()


{
Pmorph3App Pmorph3 = new Pmorph3App();
Pmorph3.LoadStaffs();
Pmorph3.DoPayroll();
}
}

4.2.12 Operator Overloading

Operator overloading allows existing C# operators to be redefined for use with user-
defined types. The overloading operator is simply another means of calling a method.
Also the feature does not fundamentally add anything to the language. Although this is
technically true, operator overloading does aid in one of the most important aspects of
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
object-oriented programming: abstraction.

Suppose that we want to aggregate a collection of Accounts for a particular customer.


Using operator overloading, we can write code similar to the following in which the +=
operator is overloaded:
Account summaryAccount = new Account ();
foreach (Account Account in customer.GetAccounts ())
{
summaryAccount += Account;
}

Page 140
C# Programming And .Net Framework

These codes have distinct benefits and include very natural syntax and the fact that the
client is abstracted from having to understand the implementation details of how the
Accounts are being aggregated. Thus, operator overloading aids in creating software that
is less expensive to write and maintain.

Operator overloading is a means of calling a method. To redefine an operator for a class,


we need only use the following pattern, where op is the operator we're overloading:
public static retval operator op ( object1 [, object2 ])
Keep in mind the following facts when using operator overloading:
All overloaded operator methods must be defined as public and static.

Technically, retval (the return value) can be any type. But common practice to return the
type for which the method is being defined with the exception of the true and false
operators, which should always return a Boolean value.

The number of arguments passed (object1, object2) depends on the type of operator being
overloaded. If a unary operator (an operator having a single operand) is being overloaded,
there will be one argument. If a binary operator (an operator taking two operands) is
being overloaded, two arguments are passed.

In the case of a unary operator, the argument to the method must be the same type as that
of the enclosing class or struct. In other words, if we redefine the! Unary operator for a
class called Pooh that method must take as its only argument a variable of type Pooh.
If the operator being overloaded is a binary operator, the first argument must be the same
type as that of the enclosing class and the second argument can be any type.

We used the += operator with an Account class. For reasons we will soon understand, we
can't actually overload these compound operators. We can overload only the "base"
operator—in this case, the +. Here's the syntax used to define the Account class's
operator+ method:

public static Account operator+ (Account Account1, Account Account2)


{
// Create a new Account object.
// Add the desired contents from
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
// Account1 to the new Account object.
// Add the desired contents from
// Account2 to the new Account object.
// Return the new Account object.
}
Let us look at a more substantial example now, one with two main classes: Account and
AccountDetailLine. The Account class has a member variable of type ArrayList that
represents a collection of all Account detail lines. To allow for the aggregation of detail
lines for multiple Accounts, we have to overloaded the + operator. The Account.
operator+ method creates a new Account object and iterates through both Account
objects' arrays of Account detail lines, adding each detail line to the new Account object.

Page 141
C# Programming And .Net Framework

This Account object is then returned to the caller. Obviously, in a real-world invoicing
module, this would be much more complex, but the point here is to show somewhat
realistically how operator overloading could be used.
using System;
using System.Collections;

class AccountDetailLine
{
double lineTotal;
public double LineTotal
{
get
{
return this.lineTotal;
}
}

public AccountDetailLine(double LineTotal)


{
this.lineTotal = LineTotal;
}
}

class Account
{
public ArrayList DetailLines;

public Account()
{
DetailLines = new ArrayList();
}

public void PrintAccount()


{
Console.WriteLine("\nLine Nbr\tTotal");
ANNAMALAI
ANNAMALAI UNIVERSITY
int i = 1;
UNIVERSITY
double total = 0;
foreach(AccountDetailLine detailLine in DetailLines)
{
Console.WriteLine("{0}\t\t{1}", i++, detailLine.LineTotal);
total += detailLine.LineTotal;
}

Console.WriteLine("=====\t\t===");
Console.WriteLine("Total\t\t{1}", i++, total);

Page 142
C# Programming And .Net Framework

public static Account operator+ (Account Account1, Account Account2)


{
Account returnAccount = new Account();

foreach (AccountDetailLine detailLine in Account1.DetailLines)


{
returnAccount.DetailLines.Add(detailLine);
}

foreach (AccountDetailLine detailLine in Account2.DetailLines)


{
returnAccount.DetailLines.Add(detailLine);
}
return returnAccount;
}
}

class AccountAddApp
{
public static void Main()
{
Account i1 = new Account();
for (int i = 0; i < 2; i++)
{
i1.DetailLines.Add(new AccountDetailLine(i + 1));
}

Account i2 = new Account();


for (int i = 0; i < 2; i++)
{
i2.DetailLines.Add(new AccountDetailLine(i + 1));
}

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Account summaryAccount = i1 + i2;

summaryAccount.PrintAccount();
}
}

4.2.13 Overloadable Operators

Only the following unary and binary operators can be overloaded.


Unary operands: +, -,!, ~, ++, --, true, false
Binary operands: +, -, *, /, %, &, |, ^, <<, >>, ==, !=, >, <, >=, <=

Page 143
C# Programming And .Net Framework

Restrictions ( on Operator Overloading )


It is not possible to overload the = assignment operator. However, when we overload a
binary operator, its compound assignment equivalent is implicitly overloaded. For
example, if we overload the + operator, the += operator is implicitly overloaded in that
the user-defined operator+ method will be called.

The [ ] operators can't be overloaded. However, user-defined object indexing is supported


through indexers. The parentheses used to perform a cast are also not overloadable.
Instead, we should use conversion operators, which are also referred to as user-defined
conversions. Operators that are currently not defined in the C# language cannot be
overloaded. It is not possible for example, define ** as a means of defining
exponentiation because C# does not define a ** operator. Also, an operator's syntax can't
be modified. We can't change the binary * operator to take three arguments when, by
definition, its syntax calls for two operands. Finally, an operator's precedence can't be
altered

4.2.14 Properties

Properties provide the opportunity to protect a field in a class by reading and writing to it
through the property. In other languages, this is often accomplished by programs
implementing specialized getter and setter methods. C# properties enable this type of
protection while also letting you access the property just like it was a field. To get an
appreciation for what properties accomplish, let's take a look at how to provide field
encapsulation by traditional methods.

Program 4-1. An Example of traditional Class Field Access: Accessors.cs

using System;

public class PropertyHolder


{
private int someProperty = 0;

public int getSomeProperty()


{
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
return someProperty;
}

public void setSomeProperty(int propValue)


{
someProperty = propValue;
}

Page 144
C# Programming And .Net Framework

public class PropertyTester


{
public static int Main(string[] args)
{
PropertyHolder propHold = new PropertyHolder();

propHold.setSomeProperty(5);

Console.WriteLine("Property Value: {0}", propHold.getSomeProperty());

return 0;
}
}

Program 4-1 shows the traditional method of accessing class fields.The PropertyHolder
class has the field we're interested in accessing. It has two methods, getSomeProperty()
and setSomeProperty(). The getSomeProperty() method returns the value of the
someProperty field. The setSomeProperty() method sets the value of the someProperty
field.

The PropertyTester class uses the methods of the PropertyHolder class to get the value of
the someProperty field in the PropertyHolder class. The Main() method instantiates a
new PropertyHolder object, propHold. Next it sets the someMethod of propHold to the
value 5 by using the setSomeProperty method. Then the program prints out the property
value with a Console.WriteLine() method call. The argument used to obtain the value of
the property is a call to the getSomeProperty() method of the propHold object. It prints
out "Property Value: 5" to the console.

This method of accessing information in a field has been good because it supports the
object-oriented concept of encapsulation. If the implementation of someProperty changed
from an int type to a byte type, this would still work. Now the same thing can be
accomplished much smoother with properties.

Program 4-2. Accessing Class Fields With Properties: Properties.cs

ANNAMALAI
ANNAMALAI UNIVERSITY
using System; UNIVERSITY
public class PropertyHolder
{
private int someProperty = 0;

public int SomeProperty


{
get
{

Page 145
C# Programming And .Net Framework

return someProperty;
}
set
{
someProperty = value;
}
}
}

public class PropertyTester


{
public static int Main(string[] args)
{
PropertyHolder propHold = new PropertyHolder();

propHold.SomeProperty = 5;

Console.WriteLine("Property Value: {0}", propHold.SomeProperty);

return 0;
}
}

Program 4-2 shows how to create and use a property. The PropertyHolder class has the
SomeProperty property implementation.Notice that the first letter of the first word is
capitalized. That's the only difference between the names of the property SomeProperty
and the field someProperty. The property has two accessors, get and set.The get accessor
returns the value of the someProperty field.The set accessor sets the value of the
someProperty field with the contents of value. The value shown in the set accessor is a
C# reserved word.

The PropertyTester class uses the SomeProperty property in the PropertyHolder class.
The first line of the Main() method creates a PropertyHolder object named propHold.
Next the value of the someProperty field of the propHold object is set to 5 by using the
SomeProperty property. It is that simple -- just assign the value to the property as if it
ANNAMALAI
ANNAMALAI UNIVERSITY
were a field. UNIVERSITY
After that, the Console.WriteLine() method prints the value of the someProperty field of
the propHold object. It does this by using the SomeProperty property of the propHold
object. Again, it is that simple -- just use the property as if it were a field itself.

Properties can be made read-only. This is accomplished by having only a get accessor in
the property implementation.

Page 146
C# Programming And .Net Framework

Program 4-3. Read-Only Property: ReadOnlyProperty.cs

using System;

public class PropertyHolder


{
private int someProperty = 0;

public PropertyHolder(int propVal)


{
someProperty = propVal;
}

public int SomeProperty


{
get
{
return someProperty;
}
}
}

public class PropertyTester


{
public static int Main(string[] args)
{
PropertyHolder propHold = new PropertyHolder(5);

Console.WriteLine("Property Value: {0}", propHold.SomeProperty);

return 0;
}
}

Program 4-3 shows how to implement a read-only property.The PropertyHolder class has
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
a SomeProperty property that only implements a get accessor. It leaves out the set
accessor. This particular PropertyHolder class has a constructor which accepts an int
parameter.

The Main() method of the PropertyTester class creates a new PropertyHolder object
named propHold. The instantiation of the propHold object uses the constructor of the
PropertyHolder that takes an int parameter. In this case, it is set to 5.This initializes the
someProperty field of the propHold object to 5.

Since the SomeProperty property of the PropertyHolder class is read-only, there is no


other way to set the value of the someProperty field. If you inserted

Page 147
C# Programming And .Net Framework

propHold.SomeProperty = 7 into the Program, the program would not compile, because
SomeProperty is read-only. When the SomeProperty property is used in the
Console.WriteLine() method, it works fine. This is because it is a read operation which
only invokes the get accessor of the SomeProperty property.

Program 4-4. Write-Only Property: WriteOnlyProperty.cs

using System;

public class PropertyHolder


{
private int someProperty = 0;

public int SomeProperty


{
set
{
someProperty = value;

Console.WriteLine("someProperty is equal to {0}", someProperty);


}
}
}

public class PropertyTester


{
public static int Main(string[] args)
{
PropertyHolder propHold = new PropertyHolder();

propHold.SomeProperty = 5;

return 0;
}
}
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Program 4-4 shows how to create and use a write-only property. This time the get
accessor is removed from the SomeProperty property of the PropertyHolder class. The
set accessor has been added, with a bit more logic. It prints out the value of the
someProperty field after it has been modified.

The Main() method of the PropertyTester class instantiates the PropertyTester class with
a default constructor. Then it uses the SomeProperty property of the propHold object to
set the someProperty field of the propHold object to 5. This invokes the set accessor of
the propHold object, which sets the value of its someProperty field to 5 and then prints
"someProperty is equal to 5" to the console.

Page 148
C# Programming And .Net Framework

4.2.15 Indexers

Indexers are real easy. They allow your class to be used just like an array. On the inside
of a class, you manage a collection of values any way you want. These objects could be a
finite set of class members, another array, or some complex data structure. Regardless of
the internal implementation of the class, its data can be obtained consistently through the
use of indexers. Here's an example.

Program 4-1. An Example of An Indexer: IntIndexer.cs

using System;

/// <summary>
/// A simple indexer example.
/// </summary>
class IntIndexer
{
private string[] myData;

public IntIndexer(int size)


{
myData = new string[size];

for (int i=0; i < size; i++)


{
myData[i] = "empty";
}
}

public string this[int pos]


{
get
{
return myData[pos];
}
setANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
{
myData[pos] = value;
}
}

static void Main(string[] args)


{
int size = 10;

Page 149
C# Programming And .Net Framework

IntIndexer myInd = new IntIndexer(size);

myInd[9] = "Some Value";


myInd[3] = "Another Value";
myInd[5] = "Any Value";

Console.WriteLine("\nIndexer Output\n");

for (int i=0; i < size; i++)


{
Console.WriteLine("myInd[{0}]: {1}", i, myInd[i]);
}
}
}

Program 4-1 shows how to implement an Indexer. The IntIndexer class has a string array
named myData. This is a private array that external users can't see. this array is initialized
in the constructor, which accepts an int size parameter, instantiates the myData array, and
then fills each element with the word "empty".

The next class member is the Indexer, which is identified by the this keyword and square
brackets, this[int pos]. It accepts a single position parameter, pos. As you may have
already guessed, the implementation of an Indexer is the same as a Property. It has get
and set accessors that are used exactly like those in a Property. This indexer returns a
string, as indicated by the string return value in the Indexer declaration.

The Main() method simply instantiates a new IntIndexer object, adds some values, and
prints the results. Here's the output:

Indexer Output

myInd[0]: empty
myInd[1]: empty
myInd[2]: empty
myInd[3]: Another Value
myInd[4]: empty
myInd[5]: Any Value
myInd[6]:
myInd[7]:
myInd[8]:
ANNAMALAI
ANNAMALAI UNIVERSITY
empty
empty
empty
UNIVERSITY
myInd[9]: Some Value

Using an integer is a common means of accessing arrays in many languages, but the C#
Indexer goes beyond this. Indexers can be declared with multiple parameters and each
parameter may be a different type. Additional parameters are separated by commas, the
same as a method parameter list. Valid parameter types for Indexers include integers,
enums, and strings. Additionally, Indexers can be overloaded. In Program 11-2, we
modify the previous program to accept overloaded Indexers that accept different types.

Page 150
C# Programming And .Net Framework

Program4-2. Overloaded Indexers: OvrIndexer.cs

using System;

/// <summary>
/// Implements overloaded indexers.
/// </summary>
class OvrIndexer
{
private string[] myData;
private int arrSize;

public OvrIndexer(int size)


{
arrSize = size;
myData = new string[size];

for (int i=0; i < size; i++)


{
myData[i] = "empty";
}
}

public string this[int pos]


{
get
{
return myData[pos];
}
set
{
myData[pos] = value;
}
}
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
public string this[string data]
{
get
{
int count = 0;

for (int i=0; i < arrSize; i++)


{
if (myData[i] == data)
{

Page 151
C# Programming And .Net Framework

count++;
}
}
return count.ToString();
}
set
{
for (int i=0; i < arrSize; i++)
{
if (myData[i] == data)
{
myData[i] = value;
}
}
}
}

static void Main(string[] args)


{
int size = 10;
OvrIndexer myInd = new OvrIndexer(size);

myInd[9] = "Some Value";


myInd[3] = "Another Value";
myInd[5] = "Any Value";

myInd["empty"] = "no value";

Console.WriteLine("\nIndexer Output\n");

for (int i=0; i < size; i++)


{
Console.WriteLine("myInd[{0}]: {1}", i, myInd[i]);
}

}
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Console.WriteLine("\nNumber of \"no value\" entries: {0}", myInd["no value"]);

Program 4-2 shows how to overload Indexers. The first Indexer, with the int parameter,
pos, is the same as in Program 11-1, but there is a new Indexer that takes a string
parameter. The get accessor of the new indexer returns a string representation of the
number of items that match the parameter value, data. The set accessor changes each

Page 152
C# Programming And .Net Framework

entry in the array that matches the data parameter to the value that is assigned to the
Indexer.

The behavior of the overloaded Indexer that takes a string parameter is demonstrated in
the Main() method of Program 4-2. It invokes the set accessor, which assigns the value of
"no value" to every member of the myInd class that has the value of "empty". It uses the
following command: myInd["empty"] = "no value";. After each entry of the myInd class
is printed, a final entry is printed to the console, indicating the number of entries with the
"no value" string. This happens by invoking the get accessor with the following code:
myInd["no value"}. Here's the output:

Indexer Output

myInd[0]: no value
myInd[1]: no value
myInd[2]: no value
myInd[3]: Another Value
myInd[4]: no value
myInd[5]: Any Value
myInd[6]: no value
myInd[7]: no value
myInd[8]: no value
myInd[9]: Some Value

Number of "no value" entries: 7

The reason both Indexers in Program 4-2 can coexist in the same class is because they
have different signatures. An Indexer signature is specified by the number and type of
parameters in an Indexers parameter list. The class will be smart enough to figure out
which Indexer to invoke, based on the number and type of arguments in the Indexer call.
An indexer with multiple parameters would be implemented something like this:

public object this[int param1, ..., int paramN]


{
get
{
// process and return some class data
}
set
{ ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
// process and assign some class data
}
}

4.2.16 Introduction to Delegates and Events

Delegates

During previous lessons, you learned how to implement reference types using language
constructs such as classes and interfaces. These reference types allowed you to create

Page 153
C# Programming And .Net Framework

instances of objects and use them in special ways to accomplish your software
development goals. Classes allow you to create objects that contained members with
attributes or behavior. Interfaces allowed you to declare a set of attributes and behavior
that all objects implementing them would publicly expose. Today, I'm going to introduce
a new reference type called a delegate.

A delegate is a C# language element that allows you to reference a method. If you were a
C or C++ programmer, this would sound familiar because a delegate is basically a
function pointer. However, developers who have used other languages are probably
wondering, "Why do I need a reference to a method?". The answer boils down to giving
you maximum flexibility to implement any functionality you want at runtime.

Think about how you use methods right now. You write an algorithm that does its thing
by manipulating the values of variables and calling methods directly by name. What if
you wanted an algorithm that was very flexible, reusable, and allowed you to implement
different functionality as the need arises? Furthermore, let's say that this was an algorithm
that supported some type of data structure that you wanted to have sorted, but you also
want to enable this data structure to hold different types. If you don't know what the types
are, how could you decide an appropriate comparison routine? Perhaps you could
implement an if/then/else or switch statement to handle well-known types, but this would
still be limiting and require overhead to determine the type. Another alternative would be
for all the types to implement an interface that declared a common method your
algorithm would call, which is actually a nice solution. However, since this lesson is
about delegates, we'll apply a delegate solution, which is quite elegant.

You could solve this problem by passing a delegate to your algorithm and letting the
contained method, which the delegate refers to, perform the comparison operation. Such
an operation is performed in Program 14-1.

Program 4-1. Declaring and Implementing a Delegate: SimpleDelegate.cs

using System;

// this is the delegate declaration


public delegate int Comparer(object obj1, object obj2);
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
public class Name
{
public string FirstName = null;
public string LastName = null;

public Name(string first, string last)


{
FirstName = first;
LastName = last;
}

Page 154
C# Programming And .Net Framework

// this is the delegate method handler


public static int CompareFirstNames(object name1, object name2)
{
string n1 = ((Name)name1).FirstName;
string n2 = ((Name)name2).FirstName;

if (String.Compare(n1, n2) > 0)


{
return 1;
}
else if (String.Compare(n1, n2) < 0)
{
return -1;
}
else
{
return 0;
}
}

public override string ToString()


{
return FirstName + " " + LastName;
}
}

class SimpleDelegate
{
Name[] names = new Name[5];

public SimpleDelegate()
{
names[0] = new Name("Joe", "Mayo");
names[1] = new Name("John", "Hancock");
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
names[2] = new Name("Jane", "Doe");
names[3] = new Name("John", "Doe");
names[4] = new Name("Jack", "Smith");
}

static void Main(string[] args)


{
SimpleDelegate sd = new SimpleDelegate();

// this is the delegate instantiation


Comparer cmp = new Comparer(Name.CompareFirstNames);

Page 155
C# Programming And .Net Framework

Console.WriteLine("\nBefore Sort: \n");

sd.PrintNames();

// observe the delegate argument


sd.Sort(cmp);

Console.WriteLine("\nAfter Sort: \n");

sd.PrintNames();
}

// observe the delegate parameter


public void Sort(Comparer compare)
{
object temp;

for (int i=0; i < names.Length; i++)


{
for (int j=i; j < names.Length; j++)
{
// using delegate "compare" just like
// a normal method
if ( compare(names[i], names[j]) > 0 )
{
temp = names[i];
names[i] = names[j];
names[j] = (Name)temp;
}
}
}
}

public void PrintNames()


{ ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Console.WriteLine("Names: \n");

foreach (Name name in names)


{
Console.WriteLine(name.ToString());
}
}
}

Page 156
C# Programming And .Net Framework

The first thing the program in Program 4-1 does is declare a delegate. Delegate
declarations look somewhat like methods, except they have the delegate modifier, are
terminated with a semi-colon (;), and have no implementation. Below, is the delegate
declaration from Program 4-1.

public delegate int Comparer(object obj1, object obj2);

This delegate declaration defines the signature of a delegate handler method that this
delegate can refer to. The delegate handler method, for the Comparer delegate, can have
any name, but must have a first parameter of type object, a second parameter of type
object, and return an int type. The following method from Program 4-1 shows a delegate
handler method that conforms to the signature of the Comparer delegate.

public static int CompareFirstNames(object name1, object name2)


{
...
}

To use a delegate, you must create an instance of it. The instance is created, similar to a
class instance, with a single parameter identifying the appropriate delegate handler
method, as shown below.

Comparer cmp = new Comparer(Name.CompareFirstNames);

The delegate, cmp, is then used as a parameter to the Sort() method, which uses it just
like a normal method. Observe the way the delegate is passed to the Sort() method as a
parameter in the code below.

sd.Sort(cmp);

Using this technique, any delegate handler method may be passed to the Sort() method at
run-time. i.e. You could define a method handler named CompareLastNames(),
instantiate a new Comparer delegate instance with it, and pass the new delegate to the
Sort() method.

ANNAMALAI
ANNAMALAI UNIVERSITY
4.2.17 Events UNIVERSITY
traditional Console applications operate by waiting for a user to press a key or type a
command and press the Enter key. Then they perform some pre-defined operation and
either quit or return to the original prompt that they started from. This works, but is
inflexible in that everything is hard-wired and follows a rigid path of execution. In stark
contrast, modern GUI programs operate on an event-based model. That is, some event in
the system occurs and interested modules are notified so they can react appropriately.
With Windows forms, there is not a polling mechanism taking up resources and you don't
have to code a loop that sits waiting for input It is all built into the system with events.

Page 157
C# Programming And .Net Framework

A C# event is a class member that is activated whenever the event it was designed for
occurs. I like to use the term "fires" when the event is activated. Anyone interested in the
event can register and be notified as soon as the event fires. At the time an event fires,
registered methods will be invoked.

Events and delegates work hand-in-hand to provide a program's functionality. It starts


with a class that declares an event. Any class, including the same class that the event is
declared in, may register one of its methods for the event. This occurs through a delegate,
which specifies the signature of the method that is registered for the event. The delegate
may be one of the pre-defined .NET delegates or one you declare yourself. Whichever is
appropriate, you assign the delegate to the event, which effectively registers the method
that will be called when the event fires. Program 4-2 shows a couple different ways to
implement events.

Program 4-1. Declaring and Implementing Events: Eventdemo.cs

using System;
using System.Drawing;
using System.Windows.forms;

// custom delegate
public delegate void Startdelegate();

class Eventdemo : form


{
// custom event
public event Startdelegate StartEvent;

public Eventdemo()
{
Button clickMe = new Button();

clickMe.Parent = this;
clickMe.Text = "Click Me";
clickMe.Location = new Point(
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
(ClientSize.Width - clickMe.Width) /2,
(ClientSize.Height - clickMe.Height)/2);

// an EventHandler delegate is assigned


// to the button's Click event
clickMe.Click += new EventHandler(OnClickMeClicked);

// our custom "Startdelegate" delegate is assigned


// to our custom "StartEvent" event.
StartEvent += new Startdelegate(OnStartEvent);

Page 158
C# Programming And .Net Framework

// fire our custom event


StartEvent();
}

// this method is called when the "clickMe" button is pressed


public void OnClickMeClicked(object sender, EventArgs ea)
{
MessageBox.Show("You Clicked My Button!");
}

// this method is called when the "StartEvent" Event is fired


public void OnStartEvent()
{
MessageBox.Show("I Just Started!");
}

static void Main(string[] args)


{
Application.Run(new Eventdemo());
}
}

You may have noticed that Program 4-2 is a Windows forms program. Although I haven't
covered Windows forms, you should know enough about C# programming in general that
you won't be lost. To help out, I'll give a brief explanation of some of the parts that you
may not be familiar with.

The Eventdemo class inherits form, which essentially makes it a Windows form. This
automatically gives you all the functionality of a Windows form, including Title Bar,
Minimize/Maximize/Close buttons, System Menu, and Borders.

The way a Windows form's application is started is by calling the Run() method of the
static Application object with a reference to the form object as its parameter. This starts
up all the underlying Windows plumbing, displays the GUI, and ensures that events are
fired as appropriate.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Below is the event declaration, which is a member of the Eventdemo class. It is declared
with the event keyword, a delegate type, and an event name.

public event Startdelegate StartEvent;

Anyone interested in an event can register by hooking up a delegate for that event. On the
next line, we have a delegate of type Startdelegate, which the event was declared to
accept, hooked up to the StartEvent event. The += syntax registers a delegate with an
event. To unregister with an event, use the -= with the same syntax.

Page 159
C# Programming And .Net Framework

StartEvent += new Startdelegate(OnStartEvent);

Firing an event looks just like a method call, as shown below:

StartEvent();

This was how to implement events from scratch, declaring the event and delegate
yourself. However, much of the event programming you'll do will be with pre-defined
events and delegates. This leads us to the other event code you see in Program 14-2,
where we hook up an EventHandler delegate to a Button Click event.

clickMe.Click += new EventHandler(OnClickMeClicked);

The Click event already belongs to the Button class and all we have to do is reference it
when registering a delegate. Similarly, the EventHandler delegate already exists in the
System namespace of the .NET Frameworks Class Library. All you really need to do is
define your callback method (delegate handler method) that is invoked when someone
presses the clickMe button. The OnClickMeClicked() method, shown below, conforms to
the signature of the EventHander delegate, which you can look up in the .NET
Framework Class Library reference.

public void OnClickMeClicked(object sender, EventArgs ea)


{
MessageBox.Show("You Clicked My Button!");
}

Any time the clickMe button is pressed with a mouse, it will fire the Click event, which
will invoke the OnClickMeClicked() method. The Button class takes care of firing the
Click event and there's nothing more you have to do.

4.2.18 Operator overloading

C# like many other programming languages has canned set of tokens that are used to
perform basic operations on intrinsic types. We have seen ,how to use the [ ] operator
with a class to programmatically index an object as if it were an array. Now let us deals
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
with closely related features of C# that provide the ability to create structure and class
interfaces that are easier and to use: operator overloading and user-defined conversions.
We will start with a general overview of operator overloading in terms of the benefits it
provides we and then look at the actual syntax for redefining the default behaviors of
operators as well as a realistic example application in which I overload the + operator to
aggregate multiple Account objects. Then we have a Program of which binary and unary
operators are overloadable as well as some of the restrictions involved. The operator
overloading will end with some design guidelines to take into account when deciding
whether to overload operators in the classes.

Page 160
C# Programming And .Net Framework

4.2.19 Interfaces

Interfaces are contracts between two disparate pieces of code. That is, once an interface is
defined and a class is defined as implementing that interface, clients of the class are
guaranteed that the class has implemented all methods defined in the interface. The key
to understanding interfaces might be to compare them with classes. Classes are objects
that have properties and methods that act on those properties. While classes do exhibit
some behavioral characteristics (methods), classes are things as opposed to behaviors,
and that's how interfaces come in. Interfaces enable

We to define behavioral characteristics, or abilities, and apply those behaviors to classes


irrespective of the class hierarchy. For example, say that We have a distribution
application in which some of the entities can be serialized. These might include the
Customer, Supplier and Invoice classes. Some other classes, such as MaintenanceView
and Document, might not be defined as serializable. The only way would be to create a
base class called something like Serializable. However, that approach has a major
drawback. A single inheritance path will not work because we do not want all the
behaviors of the class to be shared. C# does not support multiple inheritance, so there's no
way to have a given class selectively derive from multiple classes. The answer is
interfaces. Interfaces give We the ability to define a set of semantically related methods
and properties that selected classes can implement regardless of the class hierarchy.

Use of Interface
The biggest disadvantage to this technique is that it forces the client the Control Panel
code, in this case to include a lot of validation code. For example, Control Panel couldn't
just assume that any .cpl file in the folder is a Windows DLL. Also, Control Panel needs
to verify that the correction functions are in that DLL and that those functions do what
the documentation specifies. This is where interfaces come in. Interfaces let us create the
same contractual arrangement between disparate pieces of code but in a more object-
oriented and flexible manner. In addition, because interfaces are a part of the C#
language, the compiler ensures that when a class is defined as implementing a given
interface, the class does what it says it does.
In C#, an interface is a first-class concept that declares a reference type that includes
method declarations only. The term means that the feature in question is a built-in,
integral part of the language. In other words, it is not something that was bolted on after
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
the language was designed.

Declaring Interfaces

Interfaces can contain methods, properties, indexers, and events—none of which are
implemented in the interface itself. Let us look at an example to see how to use this
feature. Suppose We are designing an editor for a company that hosts different windows
controls. We are writing the editor and the routines that validate the controls users place
on the editor's form. The rest of the team is writing the controls that the forms will host.
We almost certainly need to provide some sort of form-level validation. At appropriate
times—such as when the user explicitly tells the form to validate all controls or during

Page 161
C# Programming And .Net Framework

form processing—the form could then iterate through all its attached controls and
validate each control, or more appropriately, tell the control to validate itself.
We can provide this control validation capability. This is where interfaces excel. Here's a
simple interface example containing a single method named Validate:

interface IOblivion
{
bool Validate();
}
Now We can document the fact that if the control implements the IOblivion interface, the
control can be validated.
First, We do not need to specify an access modifier such as public on an interface
method. In fact, prepending the method declaration with an access modifier results in a
compile-time error. This is because all interface methods are public by definition. In
addition to methods, interfaces can define properties, indexers, and events, as shown
here:
interface IExampleInterface
{
// Example property declaration.
int testProperty { get; }

// Example event declaration.


event testEvent Changed;

// Example indexer declaration.


string this[int index] { get; set; }
}

Implementing Interfaces

Because an interface defines a contract, any class that implements an interface must
define each and every item in that interface or the code will not compile. Using the
IOblivion example, a client class would need to implement only the interface's methods.
In the following example, the base class called ImpInter and an interface called
IOblivion. We then have a class, MyControl, that derives from ImpInter and implements
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
IOblivion. Note the syntax and how the MyControl object can be cast to the IOblivion
interface to reference its members.
using System;
public class ImpInter
{
protected string Data;
public string data
{
get

Page 162
C# Programming And .Net Framework

return this.Data;
}
set
{
this.Data = value;
}
}
}

interface IOblivion
{
bool Validate();
}

class MyControl : ImpInter, IOblivion


{
public MyControl()
{
data = "my grid data";
}

public bool Validate()


{
Console.WriteLine("Validating...{0}", data);
return true;
}
}

class InterfaceApp
{
public static void Main()
{
MyControl myControl = new MyControl();

IOblivion val = (IOblivion)myControl;


ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
bool success = val.Validate();
Console.WriteLine("The validation of '{0}' was {1}successful",
myControl.data,
(true == success ? "" : "not "));
}
}
Using the preceding class and interface definition, the editor can query the control as to
whether the control implements the IOblivion interface. If it does, the editor can validate
and then call the implemented interface methods. We will be pushed to think that, why
we just define a base class to use with this editor that has a pure virtual function called
Validate? The editor would then accept only controls that are derived from this base

Page 163
C# Programming And .Net Framework

class, right?That would be a workable solution, but it would be severely limiting. Let us
say We create our own controls and they all derive from this hypothetical base class.
Consequently, they all implement this Validate virtual method. This works until the day
we find a really cool control that we want to use with the editor. Let us say we find a grid
that was written by someone else. As such, it won't be derived from the editor's
mandatory control base class. In C++, the answer is to use multiple inheritance and
derive the grid from both the third-party grid and the editor's base class. However, C#
does not support multiple inheritance.

Using interfaces, we can implement multiple behavioral characteristics in a single class.


In C# We can derive from a single class and, in addition to that inherited functionality,
implement as many interfaces as the class needs. For example, if we wanted the editor
application to validate the contents of the control, bind the control to a database, and
serialize the contents of the control to disk, we would declare our class as follows:
public class MyGrid : ThirdPartyGrid, IOblivion,
ISerializable, IDataBound
{
}

Implementation (Using is )
In the InterfaceApp example, We saw the following code, which was used to cast an
object (MyControl) to one of its implemented interfaces (IOblivion) and then call one of
those interface members (Validate):
MyControl myControl = new MyControl();
IOblivion val = (IOblivion)myControl;
bool success = val.Validate();
The following example will compile because ISerializable is a valid interface.
Nonetheless, at run time a System. InvalidCastException will be thrown because MyGrid
does not implement the ISerializable interface. The application would then abort unless
this exception was being explicitly caught.
using System;

public class ImpInter


{
protected string Data;
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
public string data
{
get
{
return this.Data;
}
set
{
this.Data = value;
}
}

Page 164
C# Programming And .Net Framework

interface ISerializable
{
bool Save();
}

interface IOblivion
{
bool Validate();
}

class MyControl : ImpInter, IOblivion


{
public MyControl()
{
data = "my grid data";
}

public bool Validate()


{
Console.WriteLine("Validating...{0}", data);
return true;
}
}

class IsOperator1App
{
public static void Main()
{
MyControl myControl = new MyControl();

ISerializable ser = (ISerializable)myControl;

// NOTE: This will throw a System.InvalidateCastException


ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
// because the class does not implement the ISerializable
// interface.
bool success = ser.Save();

Console.WriteLine("The saving of '{0}' was {1}successful",


myControl.data,
(true == success ? "" : "not "));
}
}
Catching the exception does not change the fact that the code we want to execute will not
execute in this case. What we need is a way to query the object before attempting to cast

Page 165
C# Programming And .Net Framework

it. One way of doing this is by using the “is” operator. The “is” operator enables us to
check at run time whether one type is compatible with another type. It takes the following
form, where expression is a reference type:
expression is type
The is operator results in a Boolean value and can, therefore, be used in conditional
statements. In the following example, has beeen modified the code to test for
compatibility between the MyControl class and the ISerializable interface before
attempting to use an ISerializable method:
using System;
public class ImpInter
{
protected string Data;
public string data
{
get
{
return this.Data;
}
set
{
this.Data = value;
}
}
}
interface ISerializable
{
bool Save();
}
interface IOblivion
{
bool Validate();
}
class MyControl : ImpInter, IOblivion
{
public MyControl()
{ ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
data = "my grid data";
}

public bool Validate()


{
Console.WriteLine("Validating...{0}", data);
return true;
}
}

Page 166
C# Programming And .Net Framework

class IsOperator2App
{
public static void Main()
{
MyControl myControl = new MyControl();

if (myControl is ISerializable)
{
ISerializable ser = (ISerializable)myControl;
bool success = ser.Save();

Console.WriteLine("The saving of '{0}' was {1}successful",


myControl.data,
(true == success ? "" : "not "));
}
else
{
Console.WriteLine("The ISerializable interface is not implemented.");
}
}
}
Now that We have seen how the is operator enables us to verify the compatibility of two
types to ensure proper usage, let us look at one of its close relatives—the as operator—
and compare the two.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY

Page 167
C# Programming And .Net Framework

4.3 Revision points


Method Structure
Methods are extremely useful because they allow you to separate your logic into different
units.

Namespaces
Namespaces are C# program elements designed to help you organize your programs.

Structs
A struct allows you to create new value-type objects that are similar to the built-in types
(int, float, bool, etc.).

Exceptions
Exceptions are unforeseen errors that happen in your programs

Enum
Enums are strongly typed constants.

Classes
Classes are declared by using the keyword class followed by the class name and a set of
class members surrounded by curly braces.

Operator Overloading
Operator overloading allows existing C# operators to be redefined for use with user-
defined types

4.4 Intext Question


1. What is an interface?
2. Explain the use if Interface with an example?
3. How will you implement an Interface?
4. Describe Explicit interface?

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
5. Explain Interface Inheirtence in C# ?
6. Explain with an example how to combine two interfaces?
7. What are Delegates? Expalin
8. How will you use delegates as callback Method?
9. Define Inheritence. Write a program to explain?
10. What is an Interface?
11. What is a sealed class? Explain its significance?
12. Explain Polymorphism with an Example?
13. What do you mean by operater overloading? Illustrate with an example ?
14. What are overloadable operaters in C# ?
15. What is the restriction on operater overloading?

Page 168
C# Programming And .Net Framework

16. Explain the use of user defined conversion?


17. What is exception handling? Explain
18. What the keywords for exception handling in C#?
19. What are user defined exception . Illustrate with an example?
20. Differentiate Catch block and finally block?
21. Describe briefly Handling errors?
22. Explain the sailient features of error handling in C#?
23. Error handling improves code readability. Substantiate with an example?

4.5 Summary
In summary, you understand the structure of a method. The four types of paramters are
value, ref, out, and params. When you wish to use an instance method, you must
instantiate its object as opposed to static methods that can be called any time. The this
reference refers to its containing object and may be used to refer to its containing object's
members, including methods.

You know what a namespace is and you can declare your own namespaces. If you don't
want to type a fully qualified name, you know how to implement the using directive.
When you want to shorten a long namespace declaration, you can use the alias directive.
Also, you have been introduced to some of the other namespace members in addition to
the class type

Enums are lists of strongly typed constants with members that are symbolic names,
corresponding to an underlying integral type. Enum base types can be changed and
member values can be specified. The System.Enum BCL type is the base class of enum
types and contains methods that allow you to work with enums in different ways, such as
working with a list of names or values, converting from value to name, and converting
from name to value. For more information on the System.Enum type, see the .NET
Framework SDK documentation.

What properties are for and how they're used.traditional methods of encapsulation have
relied on separate methods.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Properties allow you to access objects state as if it was a field. Properties can be made
read-only or write-only and you know how to implement each type.

Indexers are for and how they're used. You can create an Indexer to access class
members similar to arrays. Overloaded and multi-parameter Indexers were also
covered.

Page 169
C# Programming And .Net Framework

4.6 Terminal exercises


1. The four types of paramters are _____,_____,____,____
3. _____ are lists of strongly typed constants with members that are symbolic names,
corresponding to an underlying integral type.
4. ______ allow you to access objects state as if it was a field.

4.7 Supplementary Materials


1. www.microsoft.com/mspress/books
2. msdn2.microsoft.com/en-us/vcsharp/aa336809.aspx
3. search.barnesandnoble.com/booksearch/isbnInquiry.asp?
4. www.academicresourcecenter.net/curriculum/pfv.aspx

4.8 Assignments
1. Analyse the different Inheritance and polymorphism
2. Compare Structs and Classes

4.9 Reference Books


1.Burton Harvey,Simon Robinson, Julian Templeman and Karli Watson, “C#
Programming with the Public Beta “, Shroff Publishers & Distributors Pvt.Ltd ,Mumbai
April 2001.
2.Ben Albahart, Peter Drayton and Brad Merrill, C# Essentials “, SPD Mumbai March
2001.
3.“Microsoft C# Language Specifications – WP Publications & Distributors Pvt Ltd.,
Bangalore 2001.

4.10 Learning Activities

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Learn about the Delegates more in detail

4.11 Key words


Enum – Enumeration
Structs – Structure

Page 170
C# Programming And .Net Framework

UNIT - V

5.0 Introduction
The fundamental parts of a dataset are exposed to you through standard programming
constructs such as properties and collections. The DataSet class includes the Tables
collection of data tables and the Relations collection of DataRelation objects. The
DataTable class includes the Rows collection of table rows, the Columns collection of
data columns, and the ChildRelations and ParentRelations collections of data relations.
The DataRow class includes the RowState property, whose values indicate whether and
how the row has been changed since the data table was first loaded from the database.
Possible values for the RowState property include Deleted, Modified, New, and
Unchanged. Datasets can be typed or untyped. The use of pointers is rarely required in
C#, but there are some situations that require them. The Windows Forms Class Viewer
allows you to quickly look up information about a class or series of classes, based on a
search pattern. The DateTime and TimeSpan value types differ in that a DateTime
represents an instant in time, whereas a TimeSpan represents a time interval. The
System.IO namespace contains types that allow synchronous and asynchronous reading
and writing on data streams and files. BinaryReader and BinaryWriter read and write
encoded strings and primitive data types from and to Streams.

5.1 Objective

The main objective of this chapter is give a clear idea about advance concepts of C#. The
baseclasses libraries also given to understand easily. The Mathematical and date and
time functions will give a overall idea and the connection establishment between front
end and backend by the famous connection ADO .Net is also given

5.2 Contents
5.2.1 Advance C#

Typed Dataset

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Datasets store data in a disconnected cache. The structure of a dataset is similar to that of
a relational database; it exposes a hierarchical object model of tables, rows, and columns.
In addition, it contains constraints and relationships defined for the dataset.
Note You use datasets if you want to work with a set of tables and rows while
disconnected from the data source. Using a dataset is not always an optimal solution for
designing data access.

You can create and manipulate datasets using the following portions of the .NET
Framework namespaces.

Page 171
C# Programming And .Net Framework

5.2.2 Dataset Namespace

The fundamental parts of a dataset are exposed to you through standard programming
constructs such as properties and collections. For example:
The DataSet class includes the Tables collection of data tables and the Relations
collection of DataRelation objects.

The DataTable class includes the Rows collection of table rows, the Columns collection
of data columns, and the ChildRelations and ParentRelations collections of data relations.

The DataRow class includes the RowState property, whose values indicate whether and
how the row has been changed since the data table was first loaded from the database.
Possible values for the RowState property include Deleted, Modified, New, and
Unchanged.

Datasets, Schemas, and XML

An ADO.NET dataset is one view — a relational view — of data that can be represented
in XML. In Visual Studio and the .NET Framework, XML is the format for storing and
transmitting data of all kinds. As such, datasets have a close affinity with XML. This
relationship between datasets and XML enables you to take advantage of the following
features of datasets:

The structure of a dataset — its tables, columns, relationships, and constraints — can be
defined in an XML Schema. XML Schemas are a standards-based format of the W3C
(World Wide Web Consortium) for defining the structure of XML data. Datasets can read
and write schemas that store structured information using the ReadXmlSchema and
WriteXmlSchema methods. If no schema is available, the dataset can infer one (via its
InferXmlSchema method) from data in an XML document that is structured in a
relational way. For more information about datasets and schemas,

You can generate a dataset class that incorporates schema information to define its data
structures (such as tables and columns) as class members. You can read an XML
document or stream into a dataset using the dataset's ReadXML method and write a
dataset out as XML using the dataset's WriteXML method. Because XML is a standard

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
interchange format for data between different applications, this means that you can load a
dataset with XML-formatted information sent by other applications. Similarly, a dataset
can write out its data as an XML stream or document, to be shared with other
applications or simply stored in a standard format.

You can create an XML view (an XMLDataDocument object) of the contents of a
dataset, and then view and manipulate the data using either relational methods (via the
dataset) or XML methods. The two views are automatically synchronized as they are
changed.

Page 172
C# Programming And .Net Framework

Typed versus Untyped Datasets

Datasets can be typed or untyped. A typed dataset is a dataset that is first derived from
the base DataSet class and then uses information in an XML Schema file (an .xsd file) to
generate a new class. Information from the schema (tables, columns, and so on) is
generated and compiled into this new dataset class as a set of first-class objects and
properties.

Because a typed DataSet class inherits from the base DataSet class, the typed class
assumes all of the functionality of the DataSet class and can be used with methods that
take an instance of a DataSet class as a parameter

An untyped dataset, in contrast, has no corresponding built-in schema. As in a typed


dataset, an untyped dataset contains tables, columns, and so on — but those are exposed
only as collections. (However, after manually creating the tables and other data elements
in an untyped dataset, you can export the dataset's structure as a schema using the
dataset's WriteXmlSchema method.)

You can use either type of dataset in your applications. However, Visual Studio has more
tool support for typed datasets, and they make programming with the dataset easier and
less error-prone.

Contrasting Data Access in Typed and Untyped Datasets


The class for a typed dataset has an object model in which its tables and columns become
first-class objects in the object model. For example, if you are working with a typed
dataset, you can reference a column using code such as the following:

' Visual Basic


' This accesses the CustomerID column in the first row of
' the Customers table.
Dim s As String
s = dsCustomersOrders1.Customers(0).CustomerID

// C#
// This accesses the CustomerID column in the first row of
// the Customers table.
ANNAMALAI
ANNAMALAI UNIVERSITY
string s; UNIVERSITY
s = dsCustomersOrders1.Customers[0].CustomerID;
In contrast, if you are working with an untyped dataset, the equivalent code is:
' Visual Basic
Dim s As String
s = CType(dsCustomersOrders1.Tables("Customers").Rows(0).Item("CustomerID"),
String)

// C#
string s = (string) dsCustomersOrders1.Tables["Customers"].Rows[0]["CustomerID"];

Page 173
C# Programming And .Net Framework

Typed access is not only easier to read, but is fully supported by IntelliSense in the
Visual Studio Code Editor. In addition to being easier to work with, the syntax for the
typed dataset provides type checking at compile time, greatly reducing the possibility of
errors in assigning values to dataset members. Access to tables and columns in a typed
dataset is also slightly faster at run time because access is determined at compile time, not
through collections at run time.

Even though typed datasets have many advantages, there are a variety of circumstances
under which an untyped dataset is useful. The most obvious scenario is that no schema is
available for the dataset. This might occur, for example, if your application is interacting
with a component that returns a dataset, but you do not know in advance what its
structure is. Similarly, there are times when you are working with data that does not have
a static, predictable structure; in that case, it is impractical to use a typed dataset, because
you would have to regenerate the typed dataset class with each change in the data
structure.

More generally, there are many times when you might create a dataset dynamically
without having a schema available. In that case, the dataset is simply a convenient
structure in which you can keep information, as long as the data can be represented in a
relational way. At the same time, you can take advantage of the dataset's capabilities,
such as the ability to serialize the information to pass to another process, or to write out
an XML file.

Dataset Case Sensitivity

Within a dataset, table and column names are by default case-insensitive — that is, a
table in a dataset called "Customers" can also be referred to as "customers." This matches
the naming conventions in many databases, including SQL Server, where the names of
data elements cannot be distinguished only by case.

Note Unlike datasets, XML documents are case-sensitive, so the names of data elements
defined in schemas are case-sensitive. For example, schema protocol allows the schema
to contain define a table called "Customers" and a different table called "customers." This
can result in name collisions when a schema is used to generate a dataset class.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
However, case sensitivity can be a factor in how data is interpreted within the dataset. For
example, if you filter data in a dataset table, the search criteria might return different
results depending on whether the comparison is case-sensitive or not. You can control the
case sensitivity of filtering, searching, and sorting by setting the dataset's CaseSensitive
property. All the tables in the dataset inherit the value of this property by default. (You
can override this property for each individual table.)

Page 174
C# Programming And .Net Framework

Populating Datasets

A dataset is a container; therefore, you need to fill it with data. When you populate a
dataset, various events are raised, constraint checking applies, and so on. You can
populate a dataset in a variety of ways:

Call the Fill method of a data adapter. This causes the adapter to execute an SQL
statement or stored procedure and fill the results into a table in the dataset. If the dataset
contains multiple tables, you probably have separate data adapters for each table, and
must therefore call each adapter's Fill method separately.

Manually populate tables in the dataset by creating DataRow objects and adding them to
the table's Rows collection. (You can only do this at run time; you cannot set the Rows
collection at design time.) For more information, see Adding Data to a Table.
Read an XML document or stream into the dataset. For more information, see the
ReadXml method.

Merge (copy) the contents of another dataset. This scenario can be useful if your
application gets datasets from different sources (different XML Web services, for
example), but needs to consolidate them into a single dataset. For more information, see
the DataSet.Merge method.

Record Position and Navigation in Datasets

Because a dataset is a fully disconnected container for data, datasets (unlike ADO
recordsets) do not need or support the concept of a current record. Instead, all records in
the dataset are available.Because there is no current record, there is no specific property
that points to a current record and there are no methods or properties for moving from
one record to another. (In contrast, ADO recordsets support an absolute record position
and methods to move from one record to the next.) You can access individual tables in
the dataset as objects; each table exposes a collection of rows. You can treat this like any
collection, accessing rows via the collection's index or using collection-specific
statements in your programming language.

Related Tables and DataRelation Objects


ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
If you have multiple tables in a dataset, the information in the tables might be related. A
dataset has no inherent knowledge of such relationships; to work with data in related
tables, therefore, you can create DataRelation objects that describe the relations between
the tables in the dataset. DataRelation objects can be used to programmatically fetch
related child records for a parent record, and a parent record from a child record.
For example, imagine customer and order data such as that in the Northwind database.

The Customers table might contain records such as the following:


CustomerID CompanyName City

Page 175
C# Programming And .Net Framework

ALFKI Alfreds Futterkiste Berlin


ANTON Antonio Moreno Taquerias Mexico D.F.
AROUT Around the Horn London
The dataset might also contain another table with order information. The Orders table
contains a customer ID as a foreign key column. Selecting only some of the columns in
the Orders table, it might look like the following:

OrderId CustomerID OrderDate


10692 ALFKI 10/03/1997
10702 ALFKI 10/13/1997
10365 ANTON 11/27/1996
10507 ANTON 4/15/1997

Because each customer can have more than one order, there is a one-to-many relationship
between customers and orders. For example, in the table above, the customer ALFKI has
two orders.

You can use a DataRelation object to get related records from a child or parent table. For
example, when working with the record describing the customer ANTON, you can get
the collection of records describing the orders for that customer. Similarly, if you are
working with the record describing order number 10507, you can use a DataRelation
object to get the record describing the customer for that order (ANTON).

Constraints

As in most databases, datasets support constraints as a way to ensure the integrity of data.
Constraints are rules that are applied when rows are inserted, updated, or deleted in a
table. You can define two types of constraints:

A unique constraint that checks that the new values in a column are unique in the table.
A foreign-key constraint that defines rules for how related child records should be
updated when a record in a master table is updated or deleted.

In a dataset, constraints are associated with individual tables (foreign-key constraints) or


columns (a unique constraint, one that guarantees that column values are unique).
Constraints are implemented as objects of type UniqueConstraint or
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
ForeignKeyConstraint. They are then added to a table's Constraints collection. A unique
constraint can alternatively be specified by simply setting a data column's Unique
property to true.

The dataset itself supports a Boolean EnforceConstraints property that specifies whether
constraints will be enforced or not. By default, this property is set to true. However, there
are times when it is useful to temporarily turn constraints off. Most often, this is when
you are changing a record in such a way that it will temporarily cause an invalid state.
After completing the change (and thereby returning to a valid state), you can re-enable
constraints.

Page 176
C# Programming And .Net Framework

In Visual Studio, you create constraints implicitly when you define a dataset. By adding a
primary key to a dataset, you implicitly create a unique constraint for the primary-key
column. You can specify a unique constraint for other columns by setting their Unique
property to true.

You create foreign-key constraints by creating a DataRelation object in a dataset. In


addition to allowing you to programmatically get information about related records, a
DataRelation object allows you to define foreign-key constraint rules.

Updating Datasets and Data Stores

When changes are made to records in the dataset, the changes have to be written back to
the database. To write changes from the dataset to the database, you call the Update
method of the data adapter that communicates between the dataset and its corresponding
data source.

The DataRow class used to manipulate individual records includes the RowState
property, whose values indicate whether and how the row has been changed since the
data table was first loaded from the database. Possible values include Deleted, Modified,
New, and Unchanged. The Update method examines the value of the RowState property
to determine which records need to be written to the database and what specific database
command (add, edit, delete) should be invoked.

5.2.3 Preprocessor

This section discusses the C# language's preprocessor directives:


#if
#else
#elif
#endif
#define
#undef
#warning
#error
#line
ANNAMALAI
ANNAMALAI UNIVERSITY
#region
#endregion
UNIVERSITY
While the compiler does not have a separate preprocessor, the directives described in this
section are processed as if there was one; these directives are used to aid in conditional
compilation. Unlike C and C++ directives, you cannot use these directives to create
macros.A preprocessor directive must be the only instruction on a line.

Page 177
C# Programming And .Net Framework

#if lets you begin a conditional directive, testing a symbol or symbols to see if they
evaluate to true. If they do evaluate to true, the compiler evaluates all the code between
the #if and the next directive.

#if symbol [operator symbol]...where: symbol

The name of the symbol you want to test. You can also use true and false. symbol can be
prefaced with the negation operator. For example, !true will evaluate to false. operator
(optional)

You can use the following operators to evaluate multiple symbols:

== (equality)
!= (inequality)
&& (and)
|| (or)

You can group symbols and operators with parentheses.


#if, along with the #else, #elif, #endif, #define, and #undef directives, lets you include or
exclude code based on the condition of one or more symbols. This can be most useful
when compiling code for a debug build or when compiling for a specific configuration.
A conditional directive beginning with a #if directive must explicitly be terminated with a
#endif directive.

Example
// preprocessor_if.cs
#define DEBUG
#define VC_V6
using System;
public class MyClass
{
public static void Main()
{

#if (DEBUG && !VC_V6)


Console.WriteLine("DEBUG is defined");
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
#elif (!DEBUG && VC_V6)
Console.WriteLine("VC_V6 is defined");
#elif (DEBUG && VC_V6)
Console.WriteLine("DEBUG and VC_V6 are defined");
#else
Console.WriteLine("DEBUG and VC_V6 are not defined");
#endif
}
}

Page 178
C# Programming And .Net Framework

Output

DEBUG and VC_V6 are defined

#else lets you create a compound conditional directive, such that, if none of the
expressions in the preceding #if or (optional) #elif directives did not evaluate to true, the
compiler will evaluate all code between #else and the subsequent #endif.
#else
#endif must be the next preprocessor directive after #else.
#elif lets you create a compound conditional directive. The #elif expression will be
evaluated if neither the preceding #if nor any preceding (optional) #elif directive
expressions evaluate to true. If a #elif expression evaluates to true, the compiler evaluates
all the code between the #elif and the next directive.
#elif symbol [operator symbol]... where: symbol
The name of the symbol you want to test. You can also use true and false. symbol can be
prefaced with the negation operator. For example, !true will evaluate to false.
operator (optional) You can use the following operators to evaluate multiple symbols:

== (equality)
!= (inequality)
&& (and)
|| (or)

You can group symbols and operators with parentheses.


#elif is equivalent to using:
#else
#if
But using #elif is simpler because each #if requires a #endif, whereas a #elif can be used
without a matching #endif.

Example
See #if for an example of how to use #endif.
#endif specifies the end of a conditional directive, which began with the #if directive.
#endif
A conditional directive, beginning with a #if directive, must explicitly be terminated with
a #endif directive.
ANNAMALAI
ANNAMALAI UNIVERSITY
Example
UNIVERSITY
See #if for an example of how to use #endif.
#define lets you define a symbol, such that, by using the symbol as the expression passed
to the #if directive, the expression will evaluate to true.
#define symbol where: symbol
The name of the symbol to define.
Symbols can be used to specify conditions for compilation. You can test for the symbol
with either #if or #elif. You can also use the conditional attribute to perform conditional
compilation.

Page 179
C# Programming And .Net Framework

You can define a symbol, but you cannot assign a value to a symbol. The #define
directive must appear in the file before you use any instructions that are not also
directives.

You can also define a symbol with the /define compiler option. You can undefine a
symbol with #undef.

A symbol that you define with /define or with #define does not conflict with a variable of
the same name. That is, a variable name should not be passed to a preprocessor directive
and a symbol can only be evaluated by a preprocessor directive.
The scope of a symbol created with #define is the file in which it was defined.

Example
See #if for an example of how to use #define.
#undef lets you undefine a symbol, such that, by using the symbol as the expression in a
#if directive, the expression will evaluate to false.
#undef symbol where: symbol

The name of the symbol you want to undefine.


A symbol can be defined either with the #define directive or the /define compiler option.
The #undef directive must appear in the file before you use any statements that are not
also directives.
Example
// preprocessor_undef.cs
// compile with: /d:DEBUG
#undef DEBUG
using System;
public class MyClass
{
public static void Main()
{
#if DEBUG
Console.WriteLine("DEBUG is defined");
#else
Console.WriteLine("DEBUG is not defined");

}
ANNAMALAI
ANNAMALAI UNIVERSITY
#endif UNIVERSITY
}
Output

DEBUG is not defined

#warning lets you generate a level one warning from a specific location in your code.
#warning text where: text
The text of the warning that should appear in the compiler's output.

Page 180
C# Programming And .Net Framework

A common use of #warning is in a conditional directive. It is also possible to generate a


user-defined error with #error.

Example
// preprocessor_warning.cs
// CS1030 expected
#define DEBUG
public class MyClass
{
public static void Main()
{
#if DEBUG
#warning DEBUG is defined
#endif
}
}
#error lets you generate an error from a specific location in your code.
#error text
where:
text - The text of the error that should appear in the compiler's output.
Remarks
A common use of #error is in a conditional directive. It is also possible to generate a user-
defined warning with #warning.

Example
// preprocessor_error.cs
// CS1029 expected
#define DEBUG
public class MyClass
{
public static void Main()
{
#if DEBUG
#error DEBUG is defined
#endif
}
} ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
#line lets you modify the compiler's line number and (optionally) the file name output for
errors and warnings.
#line [ number ["file_name"] | default ] where: number
The number you want to specify for the following line in a source code file. "file_name"
(optional) The file name you want to appear in the compiler output. By default, the actual
name of the source code file is used. The file name must be in double quotation marks
(""). default Resets the line numbering in a file.

Page 181
C# Programming And .Net Framework

#line might be used by an automated, intermediate step in the build process. For example,
if the intermediate step removed lines from the original source code file, but if you still
wanted the compiler to generate output based on the original line numbering in the file,
you could remove lines and then simulate the original line numbering with #line.
A source code file can have any number of #line directives.

Example
// preprocessor_line.cs
public class MyClass2
{
public static void Main()
{
#line 200
int i; // CS0168 on line 200
#line default
char c; // CS0168 on line 8
}
}

#region lets you specify a block of code that you can expand or collapse when using the
outlining feature of the Visual Studio Code Editor.
#region name where: name
The name you want to give to the region, which will appear in the Visual Studio Code
Editor.
A #region block must be terminated with a #endregion directive.
A #region block cannot overlap with a #if block. However, a #region block can be nested
in a #if block, and a #if block can be nested in a #region block.

Example
// preprocessor_region.cs
#region MyClass definition
public class MyClass
{
public static void Main()
{
}
} ANNAMALAI
ANNAMALAI UNIVERSITY
#endregion
UNIVERSITY
#endregion marks the end of a #region block.
#endregion

5.2.4 Unsafe code

The use of pointers is rarely required in C#, but there are some situations that require
them. As examples, using an unsafe context to allow pointers is warranted by the
following cases:

Page 182
C# Programming And .Net Framework

Dealing with existing structures on disk


Advanced COM or Platform Invoke scenarios that involve structures with pointers in
them

Performance-critical code

The use of unsafe context in other situations is discouraged. Specifically, an unsafe


context should not be used to attempt to "write C code in C#." Code written using an
unsafe context cannot be verified to be safe, so it will be executed only when the code is
fully trusted.

Uses pointers to copy an array of bytes. (Example 1)


Shows how to call the Windows ReadFile function. (Example 2 )
Shows how to print the Win32 version of the executable file. (Example 3
Uses pointers to copy an array of bytes (Example 1)
The following example uses pointers to copy an array of bytes from src to dst. Compile
the example with the /unsafe option.
// fastcopy.cs
// compile with: /unsafe

using System;
class Test
{
// The unsafe keyword allows pointers to be used within
// the following method:
static unsafe void Copy(byte[] src, int srcIndex,
byte[] dst, int dstIndex, int count)
{
if (src == null || srcIndex < 0 ||
dst == null || dstIndex < 0 || count < 0)
{
throw new ArgumentException();
}
int srcLen = src.Length;
int dstLen = dst.Length;
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
if (srcLen - srcIndex < count ||
dstLen - dstIndex < count)
{
throw new ArgumentException();
}
// The following fixed statement pins the location of
// the src and dst objects in memory so that they will
// not be moved by garbage collection.
fixed (byte* pSrc = src, pDst = dst)
{

Page 183
C# Programming And .Net Framework

byte* ps = pSrc;
byte* pd = pDst;
// Loop over the count in blocks of 4 bytes, copying an
// integer (4 bytes) at a time:
for (int n = count >> 2; n != 0; n--)
{
*((int*)pd) = *((int*)ps);
pd += 4;
ps += 4;
}
// Complete the copy by moving any bytes that weren't
// moved in blocks of 4:
for (count &= 3; count != 0; count--)
{
*pd = *ps;
pd++;
ps++;
}
}
}

static void Main(string[] args)


{
byte[] a = new byte[100];
byte[] b = new byte[100];
for(int i=0; i<100; ++i)
a[i] = (byte)i;
Copy(a, 0, b, 0, 100);
Console.WriteLine("The first 10 elements are:");
for(int i=0; i<10; ++i)
Console.Write(b[i] + "{0}", i < 9 ? " " : "");
Console.WriteLine("\n");
}
}

ANNAMALAI
ANNAMALAI UNIVERSITY
Example Output UNIVERSITY
The first 10 elements are:
0123456789

Code Discussion

Notice the use of the unsafe keyword, which allows pointers to be used within the Copy
method. The fixed statement is used to declare pointers to the source and destination
arrays. It pins the location of the src and dst objects in memory so that they will not be
moved by garbage collection. The objects will be unpinned when the fixed block

Page 184
C# Programming And .Net Framework

completes.The reason why unsafe code is beneficial here is that it allows copying the
array in chunks of 4 bytes at a time, and directly by incrementing pointers, thereby
getting rid of array bounds checks and address calculations in each iteration.

This example shows how to call the Windows ReadFile function from the Platform SDK,
which requires the use of an unsafe context because the read buffer requires a pointer as a
parameter.

// readfile.cs
// compile with: /unsafe
// arguments: readfile.txt
// Use the program to read and display a text file.
using System;
using System.Runtime.InteropServices;
using System.Text;
class FileRead
{
const uint GENERIC_READ = 0x80000000;
const uint OPEN_EXISTING = 3;
int handle;

public FileRead(string filename)


{
// opens the existing file...
handle = CreateFile(filename,
GENERIC_READ,
0,
0,
OPEN_EXISTING,
0,
0);
}

DllImport("kernel32", SetLastError=true)]
static extern unsafe int CreateFile(
string filename,
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
uint desiredAccess,
uint shareMode,
uint attributes, // really SecurityAttributes pointer
uint creationDisposition,
uint flagsAndAttributes,
uint templateFile);

DllImport("kernel32", SetLastError=true)]
static extern unsafe bool ReadFile(int hFile,
void* lpBuffer, int nBytesToRead,

Page 185
C# Programming And .Net Framework

int* nBytesRead, int overlapped);

DllImport("kernel32", SetLastError=true)]
static extern int GetLastError();

public unsafe int Read(byte[] buffer, int index, int count)


{
int n = 0;
fixed (byte* p = buffer)
{
ReadFile(handle, p + index, count, &n, 0);
}
return n;
}
}

class Test
{
public static void Main(string[] args)
{
FileRead fr = new FileRead(args[0]);

byte[] buffer = new byte[128];


ASCIIEncoding e = new ASCIIEncoding();

// loop through, read until done...


Console.WriteLine("Contents");
while (fr.Read(buffer, 0, 128) != 0)
{
Console.Write("{0}", e.GetString(buffer));
}
}
}

Example Input

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
The following input from readfile.txt produces the output shown in Example Output
when you compile and run this sample.
line 1
line 2

Example Output
Contents
line 1
line 2

Page 186
C# Programming And .Net Framework

Code Discussion

The byte array passed into the Read function is a managed type. This means that the
common language runtime garbage collector could relocate the memory used by the array
at will. The fixed statement allows you to both get a pointer to the memory used by the
byte array and to mark the instance so that the garbage collector won't move it.

At the end of the fixed block, the instance will be marked so that it can be moved. This
capability is known as declarative pinning. The nice part about pinning is that there is
very little overhead unless a garbage collection occurs in the fixed block, which is an
unlikely occurrence.

5.2.5 WINCV Tool – Windows Forms Class Viewer

The Windows Forms Class Viewer allows you to quickly look up information about a
class or series of classes, based on a search pattern. The class viewer displays information
by reflecting on the type using the common language runtime reflection API.

Option Description
/h Displays command syntax and options for the tool.
/hide: type Hides the specified member type. You must specify protected,
private, internal, or inherited as the type argument. If you do
not specify this option, protected, private, and internal types
are hidden by default. To specify multiple member types to
hide, specify the /hide option multiple times on the command
line separated by a space. For example, /hide: protected /hide:
private.
/nostdlib[+|-] Specifies whether to load the following default assemblies:
mscorlib.dll, System.dll, System.Data.dll, System.Design.dll,
System.DirectoryServices.dll, System.Drawing.dll,
System.Drawing.Design.dll, System.Messaging.dll,
System.Runtime.Serialization.Formatters.Soap.dll,
System.ServiceProcess.dll, System.Web.dll,
System.Web.Services.dll, System.Windows.Forms.dll,
System.XML.dll,
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY If you specify the plus symbol (+), Wincv.exe does not load
the default assemblies. The default is /nostdlib-, which loads
the default assemblies.
/r:assemblyFile Specifies an assembly to load and browse.
/show:type Displays the specified member type. You must specify
protected, private, internal, or inherited as the type argument.
If you do not specify this option, only inherited types are
displayed by default. . To specify multiple member types to
display, specify the /show option multiple times on the
command line separated by a space. For example,

Page 187
C# Programming And .Net Framework

/show:protected /show:private.
@fileName Reads the specified response file for more options.
/? Displays command syntax and options for the tool.

5.2.6 Date and Time

Represents an instant in time, typically expressed as a date and time of day.


For a list of all members of this type, see DateTime Members.
[Serializable]
public __value struct DateTime : public IComparable, IFormattable,
IConvertible
[JScript] In JScript, you can use the structures in the .NET Framework, but you cannot
define your own.

Thread Safety

Any public static (Shared in Visual Basic) members of this type are safe for
multithreaded operations. Any instance members are not guaranteed to be thread safe.

Remarks

The DateTime value type represents dates and times with values ranging from 12:00:00
midnight, January 1, 0001 C.E. (Common Era) to 12:59:59 P.M., December 31, 9999
C.E.

Time values are measured in 100-nanosecond units called ticks, and a particular date is
the number of ticks since 12:00 midnight, January 1, 1 C.E. in the GregorianCalendar
calendar. For example, a ticks value of 31241376000000000L represents the date, Friday,
January 01, 0100 12:00:00 midnight. A DateTime value is always expressed in the
context of an explicit or default calendar.

The DateTime and TimeSpan value types differ in that a DateTime represents an instant
in time, whereas a TimeSpan represents a time interval. This means, for example, that
you can subtract one instance of DateTime from another to obtain the time interval
between them. Or you could add a positive TimeSpan to the current DateTime to
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
calculate a future date.

Time values can be added to, or subtracted from, an instance of DateTime. Time values
can be negative or positive, and expressed in units such as ticks, seconds, or instances of
TimeSpan. Methods and properties in this value type take into account details such as
leap years and the number of days in a month.

Descriptions of time values in this type are often expressed using the coordinated
universal time (UTC) standard, which was previously known as Greenwich mean time
(GMT).

Page 188
C# Programming And .Net Framework

Calculations and comparisons of DateTime instances are only meaningful when the
instances are created in the same time zone. For that reason, it is assumed that the
developer has some external mechanism, such as an explicit variable or policy, to know
in which time zone a DateTime was created. Methods and properties in this class always
use the local time zone when making calculations or comparisons.

A calculation on an instance of DateTime, such as Add or Subtract, does not modify the
value of the instance. Instead, the calculation returns a new instance of DateTime whose
value is the result of the calculation.

This type inherits from IComparable, IFormattable, and IConvertible. Use the Convert
class for conversions instead of this type's explicit interface member implementation of
IConvertible.

5.2.7 Mathematical functions

Math Class [C#]


Namespace: System
Platforms: Windows 98, Windows NT 4.0, Windows Millennium Edition,
Windows 2000, Windows XP Home Edition, Windows XP Professional,
Windows .NET Server family
Assembly: Mscorlib (in Mscorlib.dll)
Provides constants and static methods for trigonometric, logarithmic, and other common
mathematical functions.
System.Object, System.Math, [Visual Basic]
NotInheritable Public Class Math
[C#]
public sealed class Math, [C++]
public __gc __sealed class Math
[JScript]
public class Math
Thread Safety
Any public static (Shared in Visual Basic) members of this type are safe for
multithreaded operations. Any instance members are not guaranteed to be thread safe.

Math Members
ANNAMALAI
ANNAMALAI UNIVERSITY
Public Fields UNIVERSITY
E Represents the natural logarithmic base,
specified by the constant, e.
PI Represents the ratio of the circumference of
a circle to its diameter, specified by the
constant, π.
16.13.2 Public Methods
Abs Overloaded. Returns the absolute value of a
specified number.
Acos Returns the angle whose cosine is the

Page 189
C# Programming And .Net Framework

specified number.
Asin Returns the angle whose sine is the
specified number.
Atan Returns the angle whose tangent is the
specified number.
Atan2 Returns the angle whose tangent is the
quotient of two specified numbers.
Ceiling Returns the smallest whole number greater
than or equal to the specified number.
Cos Returns the cosine of the specified angle.
Cosh Returns the hyperbolic cosine of the
specified angle.
Exp Returns e raised to the specified power.
Floor Returns the largest whole number less than
or equal to the specified number.
IEEERemainder Returns the remainder resulting from the
division of a specified number by another
specified number.
Log Overloaded. Returns the logarithm of a
specified number.
Log10 Returns the base 10 logarithm of a specified
number.
Max Overloaded. Returns the larger of two
specified numbers.
Min Overloaded. Returns the smaller of two
numbers.
Pow Returns a specified number raised to the
specified power.
Round Overloaded. Returns the number nearest the
specified value.
Sign Overloaded. Returns a value indicating the
sign of a number.
Sin
Sinh ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY Returns the sine of the specified angle.
Returns the hyperbolic sine of the specified
angle.
Sqrt Returns the square root of a specified
number.
Tan Returns the tangent of the specified angle.
Tanh Returns the hyperbolic tangent of the
specified angle.

Page 190
C# Programming And .Net Framework

5.2.8 Writing application with C#

Visual Studio .NET IDE

Visual Studio .NET is the comprehensive tool set for rapidly building Microsoft
Windows based applications and Web solutions. In addition to providing intuitive visual
designers, intelligent code editors, and rich data tools, Visual Studio .NET delivers an
open tools development environment that supports enhancements and customization at
every level of the product.

An Open Tools Platform for Developers

Developers integrating products with Visual Studio .NET recognizes tangible benefits for
themselves and their customers. Imagine a shorter time-to-market by focusing more time
on your company's core value-add instead of building the integrated development
environment (IDE). Imagine improvement in overall product quality and being able to
focus more on testing internally developed code by building on the stable set of reliable
IDE components in Visual Studio .NET.

Seamless integration and a consistent user interface (UI) is a boon to customers. Even
better, the whole is greater than the sum of the parts: a developer who combines Visual
Studio .NET with a modeling tool, a profiling tool, a legacy transaction interface, and a
life cycle management solution can now work with a single environment that meets all
development needs. The end user benefits by receiving a single, cohesive development
environment for all aspects of the software development life cycle.

Currently, Visual Studio .NET integrators include development life-cycle tools vendors,
programming language vendors, independent software vendors (ISVs), system
integrators, corporations, and academics.Developers can customize the Visual
Studio .NET IDE by writing macros, wizards, and add-ins that build upon the Visual
Studio .NET automation model. With the addition of the free Visual Studio Help
Integration Kit (VSHIK), authors and developers can extend help content, including
adding new Dynamic Help.

Macros

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Macros provide the fastest, easiest way to customize, extend, and automate the Visual
Studio .NET IDE. Developers can start macro development by recording a sequence of
actions, and then enhance the macro by writing additional Microsoft Visual Basic .NET
code.

Add-ins and Wizards

In addition to macros, the automation model can be accessed by creating extensions to


the IDE known as add-ins, which are compiled applications that manipulate the
environment and automate tasks. Visual Studio .NET includes extensibility projects that
help you write, build, and deploy add-ins.

Page 191
C# Programming And .Net Framework

Visual Studio Help Integration Kit

The Visual Studio .NET Help Integration Kit provides documentation and tools for
software developers and Help authors to extend the help content in Visual Studio .NET
enables component vendors, book authors, and others to provide documentation for
components, add-ins, form elements, and libraries, or to extend or enhance the Help for
Visual Studio .NET itself. We can Download the Visual Studio .NET Help Integration
Kit from MSDN.

Visual Studio .NET is a complete set of development tools for building ASP Web
applications, XML Web services, desktop applications, and mobile applications. Visual
Basic .NET, Visual C++ .NET, and Visual C# .NET all use the same integrated
development environment (IDE), which allows them to share tools and facilitates in the
creation of mixed-language solutions. In addition, these languages leverage the
functionality of the .NET Framework, which provides access to key technologies that
simplify the development of ASP Web applications and XML Web services.

5.2.9 Creating a Windows Forms application

Step 1: Create a New Windows Forms Project


Choose the New Project command from the Visual Studio® File menu to create a new
project. Choose Windows Application from the C# Projects folder as the project type. For
the project name, enter TuneTown.

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Fig 2

Step 2: Design the Main Form


Once the new project is created, Visual Studio will drop you into the Visual Studio
forms editor and present you with a blank form. Before you begin work on the form,
change the file name Main1.cs to MainForm.cs in the Solution Explorer window. While
you are at it, use the Class View window to change the form class's name from Form1 to
MainForm.

Page 192
C# Programming And .Net Framework

Now go back to the forms editor and add a list view control and three push buttons to
the form, as shown in Figure. Then, one by one, select each of the controls you added and
use the Properties window to modify the control properties as described in the following
paragraphs.

Fig3
For the list view control, edit the control properties as follows:
Set the FullRowSelect property to True.
Set the GridLines property to True.
Set the View property to Report.
Edit the Columns collection to add three columns to the header at the top of the list view:
one whose Name is "TitleHeader", whose Text is "Title", and whose Width is 100;
another whose Name is "ArtistHeader", Text is "Artist", and Width is 100; and a third
whose Name is "CommentHeader", Text is "Comment", and Width is 200.
Set Multiselect to False.
Set HideSelection to False.
Set Sorting to Ascending.
Set TabIndex to 0.
Set Name to "TuneView".
Edit the properties of the push button controls as follows:
Set the Text property to "&Add", "&Edit", and "&Remove", respectively.
Set the Name property to "AddButton", "EditButton", and "RemoveButton", respectively.
Set the TabIndex property to 1, 2, and 3, respectively.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Finally, change the Text property of the form itself to "TuneTown". Doing so will
change the title in the form's caption bar.
Step 3: Add Another Form
We need a second form that you can use to solicit input when the user clicks the Add or
Edit button. In effect, this form will serve as a dialog box. To add the form to the project,
go to the Project menu, select the Add Windows Form command, and choose Windows
Form from the ensuing dialog

Page 193
C# Programming And .Net Framework

Fig4

In the Name box, type AddEditForm.cs.


Step 4: Design the Form
Edit the new form in the Visual Studio forms editor, so that it resembles the one
shown in
Figure. Modify the label controls' properties as follows:

Fig5
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Set the Text property to "&Title", "&Artist", and "&Comment", respectively.
Set the Name property to "TitleLabel", "ArtistLabel", and "CommentLabel", respectively.
Set TabIndex to 0, 2, and 4, respectively.
Modify the edit controls' properties this way:
Set all three controls' Text properties to null.
Set Name to "TitleBox", "ArtistBox", and "CommentBox", respectively.
Set TabIndex to 1, 3, and 5, respectively.
Change the third edit control's Multiline property from False to True.
Next, modify the properties of the two push buttons:
Set Text to "OK" and "Cancel", respectively.
Set DialogResult to OK and Cancel, respectively.

Page 194
C# Programming And .Net Framework

Set Name to "OKButton" and "NotOKButton", respectively.


Set TabIndex to 6 and 7, respectively.
Finally, edit the properties of the form itself:
Set BorderStyle to FixedDialog.
Set AcceptButton to OKButton.
Set CancelButton to NotOKButton.
Set MaximizeBox and MinimizeBox to False.
Set ShowInTaskbar to False.
The forms are complete; now it is time to write some code.
Step 5: Add Properties to AddEditForm

Open AddEditForm.cs and add the statements shown in Figure . The bulk of the code
shown in Figure was created by Visual Studio. That code performs three important tasks:
It declares Button (System.WinForms.Button), TextBox (System.WinForms.TextBox),
and Label (System.WinForms.Label) fields in the AddEditForm class to represent the
form's controls. It also initializes these fields with references to instances of Button,
TextBox, and Label.

It initializes the properties of each control and of the form itself.


It physically adds the controls to the form by calling Add on the form's Controls
collection.

Most of this code is located in a method named InitializeComponent, which is called


from the class constructor. The "Component" in InitializeComponent refers to the form
itself. Most of the code that you see in the InitializeComponent method was generated at
the time you added the controls to the form and changed the controls' properties. The
statements you entered add Title, Artist, and Comment properties to the form class. These
properties permit callers to access the text in the form's edit controls.
Step 6: Add Event Handlers to MainForm

The next step is to add event handlers to the MainForm class—handlers that will be
called when the Add, Edit, or Remove button is clicked, or when an item in the list view
control is double-clicked.

In Windows Forms, controls fire events in response to user input. MainForm connects
each pushbutton's Click event to an XxxButtonClicked method, and the ListView's
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
DoubleClick event to OnItemDoubleClicked. The handlers for the Add and Edit buttons
instantiate AddEditForm and display it on the screen by calling its ShowDialog method.
ShowDialog's return value tells you how the dialog was dismissed: DialogResult.OK if
the OK button was clicked, DialogResult.Cancel if Cancel was clicked instead. To get
data in and out of the dialog, the handlers read and write the properties you added to
AddEditForm in Step 5. Once again, the forms editor provides the code that defines the
form's appearance, and you provide the code that implements its behavior.

Now it is a good time to build the project if you haven't already. You don't have to go
out to the command line; instead, you can select the Build command from the Visual

Page 195
C# Programming And .Net Framework

Studio Build menu. Then you can run TuneTown.exe by selecting one of the Debug
menu's Start commands.

Step 7: Add Anchors

TuneTown is almost complete, but there's an important element that's still missing—
an element that highlights one of the coolest features in Windows Forms. To see what I
mean, run the application and resize its main window. The window resizes just fine
(that's because the form's BorderStyle property is set to Sizable; to prevent resizing, you
could change the BorderStyle to FixedDialog), but the controls stay put. Wouldn't it be
nice if the controls flowed with the form, automatically resizing and repositioning
themselves to utilize all the real estate available to them? To do that in a traditional
Windows-based application, you'd have to handle WM_SIZE messages and
programmatically move and resize the controls. In Windows Forms, you can do it with
about one tenth of the effort. In fact, you don't have to write a single line of code.

Every Windows Form control inherits a property named Anchor from


System.WinForms.RichControl. The Anchor property describes which edges of its parent
a control's own edges should be glued to. If, for example, you set a control's Anchor
property to AnchorStyles.Right, then the distance between the control's right edge and the
right edge of the form will remain constant, even if the form is resized. By setting the
Anchor properties of the controls in MainForm, you can easily configure the push buttons
to move with the form's right edge and the list view control to stretch both vertically and
horizontally to fill the remaining space in the form. Here's how.

Open MainForm in the forms editor and select the ListView's Anchor property.
Initially, Anchor is set to TopLeft; change it to All. Then, one at a time, set the
pushbuttons' Anchor properties to TopRight. These actions result in the following
statements being added to MainForm's InitializeComponent method:
AddButton.Anchor = System.WinForms.AnchorStyles.TopRight;
EditButton.Anchor = System.WinForms.AnchorStyles.TopRight;
RemoveButton.Anchor = System.WinForms.AnchorStyles.TopRight;
TuneView.Anchor = System.WinForms.AnchorStyles.All;

Now, rebuild the application and resize the form again. This time, the controls should
flow with the form. I'm sure you've been frustrated by dialogs whose controls are too
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
small to show everything that you want them to show. Frustrations such as these will be a
thing of the past when developers take advantage of Windows Forms anchoring.

Step 8: Add Persistence


The final step is to make the data entered into TuneTown persistent by writing the
contents of the list view control to a disk file when TuneTown closes, and reading those
contents back the next time TuneTown starts up. I'll use the .NET Framework class
library's StreamWriter and StreamReader classes (members of the System.IO namespace)
to make short work of inputting and outputting text strings.

Page 196
C# Programming And .Net Framework

The necessary changes are highlighted in Figure 20. OnClosing is a virtual method
inherited from System.WinForms.Form that's called just before a form closes.
MainForm's OnClosing implementation creates a text file named TuneTownData.ttd in
the local user's application data path (SystemInformation.GetFolderPath
(SpecialFolder.LocalApplicationData)). Then it writes the text of each item and subitem
in the list view control to the file. Next time TuneTown starts up, MainForm's
InitializeListView method opens the file, reads the strings, and writes them back to the
list view.

Notice the calls to the StreamWriter and StreamReader objects' Close methods. The
reason we included these calls has to do with deterministic versus nondeterministic
destruction. Languages such as C++ employ deterministic destruction, in which objects
go out of scope (and are destroyed) at precise points in time. However, the .NET CLR,
which uses a garbage collector to reclaim resources, uses nondeterministic destruction,
meaning that there's no guarantee when (or if) the garbage collector will kick in.
Normally you do not care when garbage collection is performed. But if an object
encapsulates a non-memory resource such as a file handle, you very much want
destruction to be deterministic because you want that file handle closed as soon as it is no
longer needed. For reasons that we will not go into here, the problem is exacerbated when
StreamWriter objects are involved because a StreamWriter's Finalize method, which is
called when a StreamWriter object is destroyed, does not bother to close any file handles
or flush buffered data to disk. If you don't call Close, data could be lost. We took the
extra step of using finally blocks to enclose TuneTown's calls to Close to be sure that
Close is called, even after inopportune exceptions.

5.2.10 Data access with ADO.NET

Files and Streams


The System.IO namespace contains types that allow synchronous and asynchronous
reading and writing on data streams and files.
The following distinctions help clarify the differences between a file and a stream. A file
is an ordered and named collection of a particular sequence of bytes having persistent
storage. Therefore, with files, one thinks in terms of directory paths, disk storage, and file
and directory names. In contrast, streams provide a way to write and read bytes to and
from a backing store that can be one of several storage mediums. Just as there are several
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
backing stores other than disks, there are several kinds of streams other than file streams.
For example, there are network, memory, and tape streams.

Basic File I/O

The abstract base class Stream supports reading and writing bytes. Stream integrates
asynchronous support. Its default implementations define synchronous reads and writes
in terms of their corresponding asynchronous methods, and vice versa.

Page 197
C# Programming And .Net Framework

All classes that represent streams inherit from the Stream class. The Stream class and its
derived classes provide a generic view of data sources and repositories, isolating the
programmer from the specific details of the operating system and underlying devices.
Streams involve these fundamental operations:

Streams can be read from. Reading is the transfer of data from a stream into a data
structure, such as an array of bytes.
Streams can be written to. Writing is the transfer of data from a data structure into a
stream.

Streams can support seeking. Seeking is the querying and modifying of the current
position within a stream.

Depending on the underlying data source or repository, streams might support only some
of these capabilities. For example, NetworkStreams do not support seeking. The
CanRead, CanWrite, and CanSeek properties of Stream and its derived classes determine
the operations that various streams support.

I/O Classes Derived from System.Object

BinaryReader and BinaryWriter read and write encoded strings and primitive data types
from and to Streams.

File provides static methods for the creation, copying, deletion, moving, and opening of
files, and aids in the creation of FileStream objects. The FileInfo class provides instance
methods.

Directory provides static methods for creating, moving, and enumerating through
directories and subdirectories. The DirectoryInfo class provides instance methods.
Path provides methods and properties for processing directory strings in a cross-platform
manner.

File, Path, and Directory are sealed (in Microsoft Visual Basic, NotInheritable) classes.
You can create new instances of these classes, but they can have no derived classes.
System.IO.FileSystemInfo and Its Derived Classes FileSystemInfo is the abstract base
class for FileInfo and DirectoryInfo objects.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
FileInfo provides instance methods for the creation, copying, deletion, moving, and
opening of files, and aids in the creation of FileStream objects. The File class provides
static methods.

DirectoryInfo provides instance methods for creating, moving, and enumerating through
directories and subdirectories. The Directory class provides static methods.
FileInfo and DirectoryInfo are sealed (in Microsoft Visual Basic, NotInheritable) classes.
You can create new instances of these classes, but they can have no derived classes.

Page 198
C# Programming And .Net Framework

5.2.11 Classes Derived from System.IO.Stream

 FileStream supports random access to files through its Seek method. FileStream
opens files synchronously by default, but supports asynchronous operation as
well. File contains static methods, and FileInfo contains instance methods.
 A MemoryStream is a nonbuffered stream whose encapsulated data is directly
accessible in memory. This stream has no backing store and might be useful as a
temporary buffer.
 A NetworkStream represents a Stream over a network connection. Although
NetworkStream derives from Stream, it is not part of the System.IO namespace,
but is in the System.NET.Sockets namespace.
 A CryptoStream links data streams to cryptographic transformations. Although
CryptoStream derives from Stream, it is not part of the System.IO namespace, but
is in the System.Security.Cryptography namespace.
 A BufferedStream is a Stream that adds buffering to another Stream such as a
NetworkStream. (FileStream already has buffering internally, and a
MemoryStream does not need buffering). A BufferedStream object can be
composed around some types of streams in order to improve read and write
performance. A buffer is a block of bytes in memory used to cache data, thereby
reducing the number of calls to the operating system.
 System.IO.TextReader and Its Derived Classes
 TextReader is the abstract base class for StreamReader and StringReader objects.
While the implementations of the abstract Stream class are designed for byte input
and output, the implementations of TextReader are designed for Unicode
character output.
 StreamReader reads characters from Streams, using Encoding to convert
characters to and from bytes. StreamReader has a constructor that attempts to
ascertain what the correct Encoding for a given Stream is, based on the presence
of an Encoding-specific preamble, such as a byte order mark.
 StringReader reads characters from Strings. StringReader allows you to treat
Strings with the same API, so your output can be either a Stream in any encoding
or a String.
 System.IO.TextWriter and Its Derived Classes
 TextWriter is the abstract base class for StreamWriter and StringWriter objects.
While the implementations of the abstract Stream class are designed for byte input
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
and output, the implementations of TextWriter are designed for Unicode character
input.
 StreamWriter writes characters to Streams, using Encoding to convert characters
to bytes.
 StringWriter writes characters to Strings. StringWriter allows you to treat Strings
with the same API, so your output can be either a Stream in any encoding or a
String.

Page 199
C# Programming And .Net Framework

5.2.12 Enumerators

The FileAccess, FileMode, and FileShare enumerations define constants used by some of
the FileStream and IsolatedStorageFileStream constructors and some of the File.Open
overloaded methods. These constants affect the way in which the underlying file is
created, opened, and shared.
The SeekOrigin enumerator defines constants that specify the point of entry for random
access to files. These constants are used with byte offsets.

I/O and Security

When using the classes in the System.IO namespace, operating system security
requirements such as access control lists (ACLs) must be satisfied for access to be
allowed. This requirement is in addition to any FileIOPermission requirements.

A backing store is a storage medium, such as a disk or memory. Each different backing
store implements its own stream as an implementation of the Stream class. Each stream
type reads and writes bytes from and to its given backing store. Streams that connect to
backing stores are called base streams. Base streams have constructors that have the
parameters necessary to connect the stream to the backing store. For example, FileStream
has constructors that specify a path parameter, a parameter that specifies how the file will
be shared by processes, and so on.

The design of the System.IO classes provides simplified stream composing. Base streams
can be attached to one or more pass-through streams that provide the desired
functionality. A reader or writer can be attached to the end of the chain so that the desired
types can be read or written easily.

The following code example creates a FileStream object around the existing MyFile.txt in
order to buffer MyFile.txt. (Note that FileStreams are buffered by default.) Next, a
StreamReader is created to read characters from the FileStream, which is passed to the
StreamReader as its constructor argument. ReadLine reads until Peek finds no more
characters.
[C#]
using System;

ANNAMALAI
ANNAMALAI UNIVERSITY
using System.IO;
UNIVERSITY
public class CompBuf {
private const string FILE_NAME = "MyFile.txt";
public static void Main(String[] args) {
if (!File.Exists(FILE_NAME)) {
Console.WriteLine("{0} does not exist!", FILE_NAME);
return;
}
FileStream fsIn = new FileStream(FILE_NAME, FileMode.Open,
FileAccess.Read, FileShare.Read);
// Create a reader that can read characters from the FileStream.

Page 200
C# Programming And .Net Framework

StreamReader sr = new StreamReader(fsIn);


// While not at the end of the file, read lines from the file.
while (sr.Peek()>-1) {
String input = sr.ReadLine();
Console.WriteLine (input);
}
sr.Close();
}
}

The following code example creates a FileStream object around the existing MyFile.txt in
order to buffer MyFile.txt. (Note that FileStreams are buffered by default.) Next, a
BinaryReader is created to read bytes from the FileStream, which is passed to the
BinaryReader as its constructor argument. ReadByte reads until PeekChar finds no more
bytes.

[C#]
using System;
using System.IO;
public class ReadBuf {
private const string FILE_NAME = "MyFile.txt";
public static void Main(String[] args) {
if (!File.Exists(FILE_NAME)) {
Console.WriteLine("{0} does not exist!", FILE_NAME);
return;
}
FileStream f = new FileStream(FILE_NAME, FileMode.Open,
FileAccess.Read, FileShare.Read);
// Create a reader that can read bytes from the FileStream.
BinaryReader sr = new BinaryReader(f);
// While not at the end of the file, read lines from the file.
while (sr.PeekChar()>-1) {
byte input = sr.ReadByte();
Console.WriteLine (input);
}
sr.Close();

}
} ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
5.2.13 Accessing Data with ADO.NET

As you develop applications using ADO.NET, you will have different requirements for
working with data. In some cases, you might simply want to display data on a form. In
other cases, you might need to devise a way to share information with another company.
No matter what you do with data, there are certain fundamental concepts that you should
understand about the data approach in ADO.NET. You might never need to know some

Page 201
C# Programming And .Net Framework

of the details of data handling — for example, you might never need to directly edit an
XML file containing data — but it is very useful to understand the data architecture in
ADO.NET, what the major data components are, and how the pieces fit together.
This introduction presents a high-level overview of these most important concepts. The
topic deliberately skips over many details — for example, there is much more to datasets
than what is mentioned here — in favor of simply introducing you to ideas behind data
integration in ADO.NET.

ADO.NET Does Not Depend On Continuously Live Connections


In traditional client/server applications, components establish a connection to a database
and keep it open while the application is running. For a variety of reasons, this approach
is impractical in many applications:

Open database connections take up valuable system resources. In most cases, databases
can maintain only a small number of concurrent connections. The overhead of
maintaining these connections detracts from overall application performance.

Similarly, applications that require an open database connection are extremely difficult to
scale up. An application that does not scale up well might perform acceptably with four
users but will likely not do so with hundreds. ASP.NET Web applications in particular
need to be easily scalable, because traffic to a Web site can go up by orders of magnitude
in a very short period.

In ASP.NET Web applications, the components are inherently disconnected from each
other. The browser requests a page from the server; when the server has finished
processing and sending the page, it has no further connection with the browser until the
next request. Under these circumstances, maintaining open connections to a database is
not viable, because there is no way to know whether the data consumer (the client)
requires further data access.

A model based on always-connected data can make it difficult and impractical to


exchange data across application and organizational boundaries using a connected
architecture. If two components need to share the same data, both have to be connected,
or a way must be devised for the components to pass data back and forth.

For all these reasons, data access with ADO.NET is designed around an architecture that
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
uses connections sparingly. Applications are connected to the database only long enough
to fetch or update the data. Because the database is not holding on to connections that are
largely idle, it can service many more users.

Database Interactions - Using Data Commands

To perform operations in a database, you execute SQL statements or stored procedures


(which include SQL statements). You use SQL statements or stored procedures to read
and write rows and perform aggregate functions, such as adding or averaging. You also

Page 202
C# Programming And .Net Framework

use SQL statements or stored procedures to create or modify tables or columns, to


perform transactions, and so on.

In ADO.NET you use data commands to package a SQL statement or stored procedure.
For example, if you want to read a set of rows from the database, you create a data
command and configure it with the text of a SQL Select statement or the name of a stored
procedure that fetches records.

When you want to get the rows, you do the following:


Open a connection.
Call an execute method of the command, which in turn:
Executes the SQL statement or stored procedure referenced by the command.
Then closes the connection.
The connection stays open only long enough to execute the statement or stored
procedure.

When you call a command's execute method, it returns a value. Commands that update
the database return the number of rows affected; other types of commands return an error
code. If the command queries the database with a SELECT statement, the command can
return a set of rows. You can fetch these rows using a data reader, which acts as a very
fast read-only, forward-only cursor.

If you need to perform more than one operation — for example, read some rows and then
update them — you use multiple data commands, one for each operation. Each operation
is performed separately. For example, to read the rows, you open the connection, read the
rows, and then close the connection. When you want to update data, you again open the
connection, perform the update, and then close the connection again.
Data commands can include parameters (specifically, a collection of parameter objects)
that allow you to create parameterized queries such as the following:

Select * From customers Where (customer_id = @customerid)


You can then set the parameters at run time and execute the command to return or update
the data you want.

Caching data in Datasets

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
The most common data task is to retrieve data from the database and do something with
it: display it, process it, or send it to another component. Very frequently, the application
needs to process not just one record, but a set of them: a list of customers or today's
orders, for example. Often the set of records that the application requires comes from
more than one table: my customers and all their orders; all authors named "Smith" and
the books they have written; and other, similar, sets of related records.

Once these records are fetched, the application typically works with them as a group. For
example, the application might allow the user to browse through all the authors named
"Smith" and examine the books for one Smith, then move to the next Smith, and so on.

Page 203
C# Programming And .Net Framework

In many cases, it is impractical to go back to the database each time the application needs
to process the next record. (Doing so can undo much of the advantage of minimizing the
need for open connections.) A solution, therefore, is to temporarily store the records
retrieved from the database and work with this temporary set.

This is what a dataset is. A dataset is a cache of records retrieved from a data source. It
works like a virtual data store: A dataset includes one or more tables based on the tables
in the actual database, and it can include information about the relationships between
those tables and constraints on what data the tables can contain.

The data in the dataset is usually a much-reduced version of what is in the database.
However, you can work with it in much the same way you do the real data. While you are
doing so, you remain disconnected from the database, which frees it to perform other
tasks.

Of course, you often need to update data in the database (although not nearly as often as
you retrieve data from it). You can perform update operations on the dataset, and these
can be written through to the underlying database.

An important point is that the dataset is a passive container for the data. To actually fetch
data from the database and (optionally) write it back, you use data adapters. A data
adapter contains one or more data commands used to populate a single table in the dataset
and update the corresponding table in the database. (A data adapter typically contains
four commands, one each to select, insert, update, and delete rows in the database.)

Therefore, a data adapter's Fill method might execute a SQL statement such as SELECT
au_id, au_lname, au_fname FROM authors whenever the method is called.

Because a dataset is effectively a private copy of the database data, it does not necessarily
reflect the current state of the database. If you want to see the latest changes made by
other users, you can refresh the dataset by calling the appropriate Fill method.

One of the advantages of using datasets is that components can exchange them as
required. For example, a business object in the middle tier might create and populate a
dataset, then send it to another component elsewhere in the application for processing.
This facility means that components do not have to individually query the database.
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Datasets Are Independent of Data Sources

Although a dataset acts as a cache for data drawn from a database, the dataset has no
actual relationship with the database. The dataset is a container; it is filled by SQL
commands or stored procedures executed from a data adapter.

Because a dataset is not directly tied to a data source, it is a good integration point for
data coming from multiple sources. For example, some of the data in a dataset might
come from your database, whereas other parts of it might come from a different database

Page 204
C# Programming And .Net Framework

or a non-database source such as a spreadsheet. Some of the data in a dataset might arrive
in a stream sent by another component. Once the data is in a dataset, you can work with it
using a consistent object model, regardless of its original source.

Data Is Persisted as XML

Data needs to be moved from the data store to the dataset, and from there to various
components. In ADO.NET the format for transferring data is XML. Similarly, if data
needs to be persisted (for example, into a file), it is stored as XML. If you have an XML
file, you can use it like any data source and create a dataset out of it.

In fact, in ADO.NET, XML is a fundamental format for data. The ADO.NET data APIs
automatically create XML files or streams out of information in the dataset and send
them to another component. The second component can invoke similar APIs to read the
XML back into a dataset. (The data is not stored in the dataset as XML — for example,
you cannot parse data in a dataset using an XML parser — but instead in a more efficient
format.)

Basing data protocols around XML offers a number of advantages:

XML is an industry-standard format. This means that your application's data components
can exchange data with any other component in any other application, as long as that
component understands XML. Many applications are being written to understand XML,
which provides an unprecedented level of exchange between disparate applications.
XML is text-based. The XML representation of data uses no binary information, which
allows it to be sent via any protocol, such as HTTP. Most firewalls block binary
information, but by formatting information in XML, components can still easily
exchange the information.

For most scenarios, you do not need to know XML in order to use data in ADO.NET.
ADO.NET automatically converts data into and out of XML as needed; you interact with
the data using ordinary programming methods.

Schemas Define Data Structures

ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
Although you do not need to know anything about XML to read and write to the database
and work with datasets, there are situations in which working with XML is precisely the
goal you are after. These are situations in which you are not accessing data, but instead,
working with the design of data. To put it another way, in ADO.NET you use XML
directly when you are working with metadata.

Datasets are represented as XML. The structure of the dataset — the definition of what
tables, columns, data types, constraints, and so on are in the dataset — is defined using an
XML Schema based on the XML Schema definition language (XSD). Just as data
contained by a dataset can loaded from and serialized as XML, the structure of the dataset
can be loaded from and serialized as XML Schema.

Page 205
C# Programming And .Net Framework

For most of the work you do with data in ADO.NET, you do not have to delve deeply
into schemas. Typically, the Visual Studio .NET tools will generate and update schemas
as needed, based on what you do in visual designers. For example, when you use the
tools to create a dataset representing tables in your database, Visual Studio .NET
generates an XML Schema describing the structure of the dataset. The XML Schema is
then used to generate a typed dataset, in which data elements (tables, columns, and so on)
are available as first-class members.

However, there are times when you want to create or edit schemas yourself. A typical
example is developing a schema in conjunction with a partner or client. In that case, the
schema serves as a contract between you and the partner regarding the shape of the
XML-based data you will exchange. In that situation, you will often have to map the
schema elements to the structure of your own database.

5.2.14 Components of ADO.NET

The following illustration shows the major components of an ADO.NET application.

Fig 6

14.6.1 Using .NET Data Providers to Access Data


A data provider in the .NET Framework serves as a bridge between an application and a
data source. A data provider is used to retrieve data from a data source and to reconcile
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
changes to that data back to the data source.
The following table lists the .NET data providers that are included in the .NET
Framework.
.NET data provider Description
SQL Server .NET Data Provider For Microsoft® SQL Server™ version 7.0 or later.
OLE DB .NET Data Provider For data sources exposed using OLE DB.
An Open Database Connectivity (ODBC) .NET Data Provider is available as a separate
download at http://msdn.microsoft.com/downloads. The download includes
documentation on the classes that make up the ODBC .NET Data Provider. However, the
implementation has the same architecture as both the SQL Server .NET Data Provider

Page 206
C# Programming And .Net Framework

and the OLE DB .NET Data Provider. As a result, you can apply the information found in
this section to the ODBC .NET Data Provider as well.
The Connection, Command, DataReader, and DataAdapter objects represent the core
elements of the .NET data provider model. The following table describes these objects.

Object Description
Connection Establishes a connection to a specific data source.
Command Executes a command against a data source.
DataReader Reads a forward-only, read-only stream of data from a data source.
DataAdapter Populates a DataSet and resolves updates with the data source.

Along with the core classes listed in the preceding table, a .NET data provider also
contains the classes listed in the following table.

Object Description
Transaction Enables you to enlist commands in transactions at the data source.
CommandBuilder A helper object that will automatically generate command properties
of a DataAdapter or will derive parameter information from a stored
procedure and populate the Parameters collection of a Command
object.
Parameter Defines input, output, and return value parameters for commands
and stored procedures.
Exception Returned when an error is encountered at the data source. For an
error encountered at the client, .NET data providers throw a .NET
Framework exception.
Error Exposes the information from a warning or error returned by a data
source.
ClientPermission Provided for .NET data provider code access security attributes.

Some of the packaging and deployment story for the .NET Framework is described in
other sections of the .NET Framework SDK documentation. These sections provide
information about the self-describing units called assemblies, which require no registry
entries, strong-named assemblies, which ensure name uniqueness and prevent name
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
spoofing, and assembly versioning, which addresses many of the problems associated
with DLL conflicts. This section provides information about packaging and distributing
.NET Framework applications.

Page 207
C# Programming And .Net Framework

5.3 Revision points


Typed Dataset

Datasets store data in a disconnected cache. The structure of a dataset is similar to that of
a relational database; it exposes a hierarchical object model of tables, rows, and columns.
In addition, it contains constraints and relationships defined for the dataset.

Dataset Namespace

The fundamental parts of a dataset are exposed to you through standard programming
constructs such as properties and collections.

Datasets, Schemas, and XML

An ADO.NET dataset is one view — a relational view — of data that can be represented
in XML. In Visual Studio and the .NET Framework, XML is the format for storing and
transmitting data of all kinds. As such, datasets have a close affinity with XML

Typed versus Untyped Datasets

Datasets can be typed or untyped. A typed dataset is a dataset that is first derived from
the base DataSet class and then uses information in an XML Schema file (an .xsd file) to
generate a new class.

Dataset Case Sensitivity

Within a dataset, table and column names are by default case-insensitive — that is, a
table in a dataset called "Customers" can also be referred to as "customers."

5.4 Intext Question


1. What are the fundamental operationd of the streams?
2. What are the classes derived from System.IO sream?
3. Differentiate the legacy connection and the data access with ADO.Net?
ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
4. What bis the format used to transfer data in ADO.Net. What are its advantages?
5. How will you cache data in a data set?
6. Explain the components od ADO.Net. Illustrate with help of a block diagram?
7. What are the options provided by .Net frame work in
8. Packaging Application.
9. Distribution application.
10. What is a data set Explain?
11. Differentiate Typed dataset and Untyped dataset?
12. How will you populate a dataset?
13. Explain the functions of Assemblies in .Net Framework?
14. What are the uses of reflection?

Page 208
C# Programming And .Net Framework

15. Explain COM Interoperability?


16. How will you call a .net component from COM?
17. What is Marshalling. Expalin its use with respect to Custom Interfaces?
18. Explain .Net remoting?
19. Explain ASP.NET web application with help of a diagram?
20. Explain VS.Net IDE?
21. Write the steps involved in creating windows forms using VS.NET IDE?

5.5 Summary
 The fundamental parts of a dataset are exposed to you through standard
programming constructs such as properties and collections.
 The DataSet class includes the Tables collection of data tables and the Relations
collection of DataRelation objects.
 The DataTable class includes the Rows collection of table rows, the Columns
collection of data columns, and the ChildRelations and ParentRelations
collections of data relations.
 The DataRow class includes the RowState property, whose values indicate
whether and how the row has been changed since the data table was first loaded
from the database. Possible values for the RowState property include Deleted,
Modified, New, and Unchanged. Datasets can be typed or untyped.
 The use of pointers is rarely required in C#, but there are some situations that
require them.
 The Windows Forms Class Viewer allows you to quickly look up information
about a class or series of classes, based on a search pattern.
 The DateTime and TimeSpan value types differ in that a DateTime represents an
instant in time, whereas a TimeSpan represents a time interval.
 The System.IO namespace contains types that allow synchronous and
asynchronous reading and writing on data streams and files.
 BinaryReader and BinaryWriter read and write encoded strings and primitive data
types from and to Streams.

5.6 Terminal exercises


ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
1. A ________ is a dataset that is first derived from the base DataSet class and then uses
information in an XML Schema file (an .xsd file) to generate a new class.
2. Within a dataset, table and column names are by default _________
3. A dataset is a ______; therefore, you need to fill it with data.
4. If you have multiple tables in a ______, the information in the tables might be related.
5. When changes are made to records in the dataset, the changes have to be written back
to the _______.
6. While the compiler does not have a separate _________, these directives are used to
aid in conditional compilation.

Page 209
C# Programming And .Net Framework

5.7 Supplementary Materials


1. www.microsoft.com/mspress/books
2. msdn2.microsoft.com/en-us/vcsharp/aa336809.aspx
3. search.barnesandnoble.com/booksearch/isbnInquiry.asp?
4. www.academicresourcecenter.net/curriculum/pfv.aspx

5.8 Assignments
1. Analyse the different typea of data base connections
2. Compare data set and record set

5.9 Reference Books


1.Burton Harvey,Simon Robinson, Julian Templeman and Karli Watson, “C#
Programming with the Public Beta “, Shroff Publishers & Distributors Pvt.Ltd ,Mumbai
April 2001.
2.Ben Albahart, Peter Drayton and Brad Merrill, C# Essentials “, SPD Mumbai March
2001.
3.“Microsoft C# Language Specifications – WP Publications & Distributors Pvt Ltd.,
Bangalore 2001.

5.10 Learning Activities


Learn about the ADO .Net connectivity in detail

5.11 Key words


WINCV Tool - Windows Forms Class Viewer
GMT -Greenwich mean time.
UTC -coordinated universal time.
UI - user interface.
ISV ANNAMALAI
ANNAMALAI UNIVERSITY
UNIVERSITY
- independent software vendors

Page 210

You might also like