VTU MCA .NET Notes
VTU MCA .NET Notes
VTU MCA .NET Notes
Bandari Ravikiran
Ravikiran
Contents
1 Philosophy of .NET 7
1.1 Life Before .NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2 .NET Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3 Building blocks of .NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3.1 Common Lanugage Runtime (CLR) . . . . . . . . . . . . . . . . . . . . . 12
1.3.2 Common Type System(CTS) . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3.3 Cross Language Specification (CLS) . . . . . . . . . . . . . . . . . . . . . 12
1.4 Base Class Library[BCL) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.5 C# Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.5.1 C# Language Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.6 Overview of .NET Assemblies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.7 Common Intermediate Language (CIL) . . . . . . . . . . . . . . . . . . . . . . . . 15
1.7.1 Advantages of CIL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.7.2 Compiling CIL to platform specific Instructions . . . . . . . . . . . . . . . 16
1.8 Common Type System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.8.1 Built - In Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.9 Common Language Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.10 Common Language Runtime(CLR) . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.10.1 Features of CLR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.11 Namespaces in .NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.11.1 Accessing a Namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.12 Deploying .NET Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2 Building C# Applications 23
2.1 C# Command Line Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.1.1 Configuring the C# Command-Line Compiler . . . . . . . . . . . . . . . . 23
2.1.2 Configuring Additional .NET Command-Line Tools . . . . . . . . . . . . 23
2.2 Building C# Applications using csc.exe . . . . . . . . . . . . . . . . . . . . . . . 24
2.2.1 Referencing External Assemblies . . . . . . . . . . . . . . . . . . . . . . . 25
2.3 csc.exe Response Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3.1 The Default Response File(csc.rsp) . . . . . . . . . . . . . . . . . . . . . . 26
2.4 Generating Bug Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.5 Remaining C# Compiler Options . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.6 The Command Line Debugger (cordbg.exe) . . . . . . . . . . . . . . . . . . . . . 29
2.6.1 Debugging at Command Line . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.7 Using Visual Studio - .NET IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.7.1 The VS.NET Start Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3
4 CONTENTS
3 C# Language Fundamentals 43
3.1 Anatomy of C# Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.1.1 Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.1.2 Modifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.1.3 Main Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.2 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.2.1 Types of Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.3 System.Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.3.1 Basic Input and Output with the Console Class . . . . . . . . . . . . . . . 48
3.3.2 Formatting Console output . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.3.3 Formatting Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.3.4 Custom Number Formatting . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.3.5 Date Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.3.6 Custom Date Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.4 Default values for variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3.5 Variable Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3.6 Member Variable Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.7 Value Types and Reference Types . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.7.1 Value Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.7.2 Reference Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.8 Boxing and Unboxing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.8.1 Boxing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.8.2 UnBoxing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.9 System.Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.10 Constant Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3.10.1 const modifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3.10.2 By using readonly modifer . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
3.11 Iteration Constructs in C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
3.11.1 while loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
3.11.2 do-while loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.11.3 for loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.11.4 foreach loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
3.12 Flow Control statements in C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
3.12.1 Jump Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
3.12.2 Selection Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Ravikiran
CONTENTS 5
3.13 C# Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
3.14 Defining Custom Class Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
3.15 Static Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
3.16 Method Parameter Modifiers in C# . . . . . . . . . . . . . . . . . . . . . . . . . 67
3.16.1 Value parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
3.16.2 Reference parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
3.16.3 Output Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
3.16.4 Parameter arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
3.17 Arrays in C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
3.17.1 Array Bounds Checking . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.17.2 Multi Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.17.3 System.Array class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.18 String Manipulation in C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
3.18.1 String Manipulation Methods . . . . . . . . . . . . . . . . . . . . . . . . . 73
3.18.2 System.Text.StringBuilder Class . . . . . . . . . . . . . . . . . . . . . . . 75
3.18.3 Escape Characters and Verbatim Strings . . . . . . . . . . . . . . . . . . . 75
3.19 Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
3.19.1 System.Enum class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Ravikiran
6 CONTENTS
Ravikiran
Chapter 1
Philosophy of .NET
C Language
The main philosophy of C Language is ”Programmers know what to do”, but it does not
help or assist or warn you about anything, unless there is some syntactical error like some type
mismatch, or some macro redefinition, or some array’s index goes out of bound, etc...
Main drawbacks of C Language are
1. Concept of Pointers is the powerful feature of C Language. But, they are highly insecure
and makes it vulnerable.
2. The concept of re usability is achieved only through functions, so it makes it more complex
for coding big projects as we have to write everything from scratch and hence lot of time
is wasted.
4. Since C is structured language, it lacks all the benefits of object oriented programming
concepts like Abstraction, Encapsulation, Inheritance and Polymorphism
Besides all these, C is a powerful language, thats why, a majority of Operating Systems are built
using C.
C++ Language
C++ was designed at AT & T Bell Labs by Bjarne Stroustrup in the early 80s. The main
features of C++ are
• Stronger typechecking
7
8 CHAPTER 1. PHILOSOPHY OF .NET
• It does not support versioning i.e. creation and management of multiple versions of a
software. All versions have the same general function but they are improved, upgraded or
customized. New versions of software modules can work with existing applications
• C++ still support pointers which will leads to major errors in programs and also it
makes C++ programs highly insecure
3. In VB, there is no need to specify the type of a variable, or even declaring the variable
itself. This provide an advantage of using a variable without having to worry about, or
even knowing about the data type or size of the variable.
Drawbacks of VB are
3. We have to distribute a runtime with all of our applications (or install it to the computer
before you use the application). This adds to a larger download (not all versions of windows
have the VB6 runtime and even less have the .Net framework). The minimum distribution
package is greater than 1 floppy. This is because the VB 6.0 run-time must be included.
Ravikiran
1.1. LIFE BEFORE .NET 9
4. As there is no need to declare the data type of variables prior to its usage, there will be
more chances to get runtime errors
5. Every time you create a new form or code file, you must remember to specify the directory
where you want it stored. There is no default setting to specify that new code for a specific
project should default to a specific directory.
JAVA / J2EE
Java is one of the most popular programming language, because of its following features..
1. It is Platform Independent
2. It contains large number of predefined packages that contain various type definitions.
3. Java programmers can build pure Java applications complete with database connec-
tivity, messaging support, web-enabled front ends, and a richer user interface
6. Garbage collection is one of the powerful feature of JAVA which automatically cleans the
memory.
Like any programming language, Java is not without drawbacks. Here are some of the drawbacks
of JAVA...
1. Java applets are not supported by all the browsers and they need separate plug-in to be
installed
2. Java developers have less control over on garbage collection to free objects
3. Primary goal of Java is to make Java as a single programming language for every need. So
Java offers a little chance for language integration.
COM
Component Object Model, abbreviated as COM, is Microsofts framework for developing and
supporting component objects. It enables interprocess communication and dynamic object cre-
ation. COM is an architecture that says ”If you build your classes in accordance with the rules
of COM, you end up with a block of reusable binary code”.
The COM model has come into widespread use since its introduction by Microsoft and it is an
integral part of many Microsoft applications and technologies, including Internet Explorer and
the Office suite of applications.
Unlike traditional software development, which required each application to be built from scratch,
COM allows developers to create complex applications using a series of small software objects.
Ravikiran
10 CHAPTER 1. PHILOSOPHY OF .NET
COM lets developers make portions of their applications using components. For example, a
component might be a tax calculation engine or the business rules for a price list.
This approach speeds up the development process by allowing several teams to work on separate
parts at the same time. Developers can also reuse components from one project to the next, and
they can easily swap out or update a particular component without affecting other portions of
the application.
1. The primary advantage of the Component Object Model is that it is founded on the object-
oriented principles
2. It has given rise to the development of popular technologies like COM+ and the .NET
framework. COM+ provides the users with support for distributed transactions. The
.NET framework has taken over the COM platform and is largely being used for software
development
3. COM technology is perhaps the most suitable means of developing and deploying desktop
applications
4. COM can best be described as an infrastructure that allows building speedy, and extensible
component-based software
2. Business logic
3. Data Storage
Ravikiran
1.2. .NET FEATURES 11
1. DNA is quite complex because of the fact that Windows DNA requires the use of numerous
technologies and languages (ASP, HTML, XML, JavaScript, VBScript, and COM(+), as
well as a data access API such as ADO).
2. Each technology is different from other technology in their syntax and also in semantics.
So when they are combined in DNA, it may results in highly confused mishmash of tech-
nologies.
• .NET is multi-lingual With the .NET platform we can use several languages, such as
C++, JScript, VB.NET, C# etc... All these languages are combined via an intermediate
binary code, which is independent of hardware and operating systems. This intermediate
language called Microsoft Intermediate Language (MSIL) is then executed in the
Common Language Runtime(CLR) which is the execution environment of .NET applica-
tions
• .NET Applications are portable Applications compiled as intermediate code are pre-
sented as Portable Executables (PEs). These PEs can be implemented over a vast
range of hardware and software architectures: Intel PCs with windows 9x, Windows NT4,
Windows 2000 or 64 bit windows versions, PocketPC and other operating systems.
• All Languages must agree with a common agreement For a language to be eligi-
ble for the range of languages supported by the .NET platform, it must provide a set of
possibilities and constructions listed in the agreement called Common Language Spec-
ification (CLS). To add a language to .NET, all that is required is for it to meet the
requirements of the CLS, and a compiler to convert that language into MSIL.
• Managed Codes All Code in .NET is managed code because the runtime provides ser-
vices that include automatic memory management, debugging support, enhanced security.
Earlier, the developers had to explicitly manage the memory in languages like C++.
• Complete and total language integration: Unlike COM, .NET supports cross-language
inheritance, cross-language exception handling, and cross-language debugging.
• Base class library: .NET framework provides a class library that offers a consistent
object model used by all .NET-aware languages.
Ravikiran
12 CHAPTER 1. PHILOSOPHY OF .NET
same set of APIs and also have the same data types as specified by the Common Type
Specification (CTS)
Ravikiran
1.5. C# LANGUAGE 13
manipulation, which makes the programmer’s job easier. The BCL is sometimes incorrectly
referred to as the Framework Class Library (FCL), which is a superset including the Microsoft.*
namespaces
1.5 C# Language
Microsoft has developed a new programming language, C# (pronounced ”see sharp”), specifically
for this new platform. C# is a programming language that looks very similar (but not identical)
to the syntax of Java. C# is primarily derived from the C, C++, and Java programming
languages with some features of Microsoft’s Visual Basic in the mix.
• No pointers required c# programs typically have no need for direct pointer manipulation
• Since it‘s on .NET, it inherits the features of automatic memory management and
garbage collection.
• C# has been based according to the current trend and is very powerful and simple for
building interoperable, scalable, robust applications.
• As of C# 2005, the ability to build generic types and generic members using a
syntax very similar to C++ templates.
• The C++-like ability to overload operators for a custom type, without the complexity
As C# comes along with .NET platform, it can only produce code that can execute within the
.NET runtime. Officially speaking, the term used to describe the code targeting the .NET runtime
is managed code. The binary unit that contains the managed code is termed an assembly and
the code that cannot be directly hosted by the .NET runtime is termed as unmanaged code.
Ravikiran
14 CHAPTER 1. PHILOSOPHY OF .NET
In the Microsoft .NET framework, an assembly is a partially compiled code library for use
in deployment, versioning and security. The .NET assembly is the standard for components
developed with the Microsoft.NET. Dot NET assemblies may or may not be executable, i.e.,
they might exist as the executable (.exe) file or dynamic link library (.dll) file. All the .NET
assemblies contain the definition of types, versioning information for the type and meta-data.
.NET assemblies do not contain platform specific instructions.
When a *.dll or *.exehas been created using a .NET-aware compiler, the resulting module is bun-
dled into an assembly. An assembly contains CIL (Common Intermediate Language) code, which
is conceptually similar to Java bytecode and it is not compiled to platform specific instructions.
In addition to CIL instructions , assemblies also contain metadata that describes the various
characteristics of every ”type” described with in the binary assembly. Finally, in addition to CIL
and type metadata, assemblies themselves are also described using metadata, which is officially
termed as manifest. The manifest contains information about the current version of the assembly,
culture information (used for localizing string and image resources), and a list of all externally
referenced assemblies that are required for proper execution.
A .NET assembly may contain the following elements:
1. Assembly Manifest :An assembly manifest is metadata inside an assembly that describes
everything there is to know about the assembly and its contents. The manifest contains:
(a) Strong Name - The assembly’s name, version, culture, optional processor architec-
ture, and public key (for shared assemblies)
(b) File Contents - Name and hash of all files in the assembly
(c) Type List - Types defined in the assembly, including public types that are exported
from the assembly
(d) Resource List - Icons, images, text strings and other resources contained in the
assembly
(e) Dependencies - Compile-time dependencies on other assemblies
Ravikiran
1.7. COMMON INTERMEDIATE LANGUAGE (CIL) 15
3. Type Metadata : Defines all types, their properties and methods, and most importantly,
public types exported from this assembly
1. A single *.dll or *.exe file which contains the CIL code, metadata, manifest and optional
resources in one binary package.
2. This is the simplest type of assemblies. It contains the type information and implementation
as well as the assembly’s manifest into a single physical file.
3. Class Libraries, Windows Forms / WPF applications, Console applications and Windows
Services are all examples of single file assemblies.
Multi-file assemblies: An assembly can consist of one or more files called modules. Exactly
one of these modules contains the assembly manifest. Note that the files in a multi-file assembly
can reside in separate locations and are linked together with the assembly manifest.
Multi-file assemblies are rare, and Visual Studio doesn’t directly support their creation. The
most common reason for multi-file assemblies is when a single assembly combines code from
multiple programming languages.
Ravikiran
16 CHAPTER 1. PHILOSOPHY OF .NET
2. Platform Independence As CIL doesn’t emit any platform specific code, CIL is an plat-
form independent code. Besides, there is an international standard for the C# language,
and a large subset of the .NET platformand implementations already exist for many non-
Windows operating systems
Ravikiran
1.8. COMMON TYPE SYSTEM 17
3. Defines rules that languages must follow, which helps ensure that objects written in different
languages can interact with each other.
There are two general types of categories in .Net Framework that Common Type System support.
They are value types and reference types. Value types contain data and are user-defined or built-
in. they are placed in a stack or in order in a structure. Reference types store a reference of the
values memory address. They are allocated in a heap structure. You can determine the type
of a reference by the values of self-describing types. Reference types can be categorized into
self-describing types, pointer types, or interface types.
There are five different types defined in .NET framework
1. CTS Class Type : Every .NET-aware language supports, the notion of a class type,
which is the cornerstone of object-oriented programming (OOP). A class may be composed
of any number of members (such as properties, methods, and events) and data points
(fields).
2. CTS Structure Type : The concept of a structure is also formalized under the CTS. A
structure can be thought of as a lightweight class type having value-based semantics
3. CTS Interface Types : Interfaces are nothing more than a named collection of abstract
member definitions, which may be supported (i.e., implemented) by a given class or struc-
ture.
4. CTS Enumeration Types :Enumerations are a handy programming construct that al-
lows us to group name/value pairs.
5. CTS Delegate Types Delegates are equivalent to function pointers in C Language. The
key difference is that a .NET delegate is a class that derives from System.MulticastDelegate,
rather than a simple pointer to a raw memory address.
6. CTS Member Types : A type member can be either constructor or finalizer or static
constructor or nested type or operator or method or property or indexer or field or read
only field or constant or event.
Ravikiran
18 CHAPTER 1. PHILOSOPHY OF .NET
The most important rules, and which apply to public and protected members are
2. Array elements must have a CLS-compliant element type. Arrays must also be 0-indexed
Ravikiran
1.10. COMMON LANGUAGE RUNTIME(CLR) 19
for managing memory allocation, starting up and killing processes, and enforcing security policy,
as well as satisfying any dependencies that the component might have on other components.
Programmatically speaking, the term runtime can be understood as a collection of external ser-
vices that are required to execute a given compiled unit of code
The CLR makes it easy to design components and applications whose objects interact across
languages. Objects written in different languages can communicate with each other, and their
behaviors can be tightly integrated.
5. Garbage Collection
6. High Performance
7. Reusability
Ravikiran
20 CHAPTER 1. PHILOSOPHY OF .NET
In this example we create two namespaces. These namespaces have hierarchical structure - outer
one named OutNamespace and the inner one called WorkNamespace. The inner namespace is
declared with a C# .Net class WorkItem.
1. using name
Ravikiran
1.12. DEPLOYING .NET FRAMEWORK 21
Here, name specifies the name of the namespace we want to access. All of the members
defined in the specified namespace will now become the part of the current namespace.
Using directive should be specified at the top of the file, prior to any other declarations.
However, if you deploy an assembly to a computer that does not have .NET installed, it will fail
to run. For this reason, Microsoft provides a setup package named dotnetfx.exethat can be freely
shipped and installed along with your custom software. This installation program is included
with the .NET Framework 2.0 SDK, and it is also freely downloadable from Microsoft. Once
dotnetfx.exeis installed, the target machine will now contain the .NET base class libraries, .NET
runtime ( mscoree.dll), and additional .NET infrastructure (such as the GAC).
Ravikiran
22 CHAPTER 1. PHILOSOPHY OF .NET
Ravikiran
Chapter 2
Building C# Applications
There are a number of techniques to compile C# source code. Most of the .NET programmers
use Visual Studio in order to create .NET assemblies. Apart from visual studio, we can also use
C# command-line compiler - csc.exe tool (where csc stands for C-Sharp Compiler). This tool is
included with the .NET Framework 2.0 SDK. But using csc.exe alone is very difficult to build a
large-scale application however it is important to understand the basics of how to compile *.cs
files.
1. Right-click the My Computer icon and select Properties from the pop-up menu.
2. Select the Advanced tab and click the Environment Variables button.
3. Double-click the Path variable from the System Variables list box.
4. Add the following line to the end of the current Path value (note each value in the Path
variable is separated by a semicolon):
C:/Windows/Microsoft.NET/Framework/v2.0.50215
23
24 CHAPTER 2. BUILDING C# APPLICATIONS
using System;
class TestApp
{
public static void Main() {
Console.WriteLine(”Testing! 1, 2, 3”); }
}
Save the above program in a convenient location (e.g, C:/CscExample) as TestApp.cs. Before
compiling the above program, we have to know the different options of C# compiler. The
following are the some of the options of C# Compiler. To compile TestApp.csinto a console
Option Purpose
/out This option is used to specify the name of the assembly to be
created. By default, the assembly name is the same as the name of the initial
input *.cs file (in the case of a *.dll) or the name of the type containing the
programs Main()method (in the case of an *.exe).
/target:exe This option builds an executable console application. This is the
default file output type, and thus may be omitted when building
this application type.
/target:library This option builds a single-file *.dllassembly.
/target:module This option builds a module. Modules are elements of multifile assemblies
/target:winexe Although you ar e free to build Windows-based applications
using the /target:exe flag, the /target:winexeflag
prevents a console window from appearing in the background.
application named TestApp.exe, change to the dir ectory containing your source code file and
enter the following command
Ravikiran
2.3. CSC.EXE RESPONSE FILES 25
When we compile the C# program, we can get the exe file of the compiled program having the
same name of the file that is compiled.
After compiling the TestApp.cs file, we will get TestApp.exe file and it can be executed by typing
its file name
C:/i TestApp.exe
Testing! 1,2,3
using System;
using System.Windows.Forms;
class ExternalAssemblyDemo
{
public static void Main(string[] args)
{
MessageBox.Show(”Hello...”);
}
}
if you need to reference numerous external assemblies using c sc.exe, then we have to simply list
each assembly using a semicolon-delimited list.
For example
csc /r:System.Windows.Forms.dll;System.Drawing.dll *.cs
Ravikiran
26 CHAPTER 2. BUILDING C# APPLICATIONS
Then, replace the lengthy command line switches with the name of the relevent response file for
the current compilation using the @ symbol:
csc @commandLine01.rsp
When we specify /bugreport, we will be prompted to enter correct information for the pos-
sible error(s) at hand, which will be saved (along with other details) into the file you specify.
For Example...
using System;
class DebugClass
{ static void Main(string[] args)
Ravikiran
2.4. GENERATING BUG REPORTS 27
{
Console.WriteLine(”Hai”);
Console.Readey(); //Compile Time Error
}
}
In the above example, we have one error in the line 7. I have written Console.Readey() insetead
of Console.ReadKey(). So, when we compile the above program as ...
then will be prompted to enter corrective action for the error at hand. All This information is
stored in file that is specified with the /bugreport flag (here it is BugFile.txt)
Ravikiran
28 CHAPTER 2. BUILDING C# APPLICATIONS
Ravikiran
2.6. THE COMMAND LINE DEBUGGER (CORDBG.EXE) 29
and if there are no any compilation errors, the csc.exe tool will generates the DebugClass.pdb
(pdb stands for Program Debug Database), DebugClass.exe files
Once you have a valid *.pdb file, we can open a session with cordbg.exe by specifying your
.NET assembly(here DebugClass.exe) as a command line argument (the *.pdb file will be loaded
automatically): cordbg.exe testapp.exe
cordbg DebugClass.exe
At this point, you are in debugging mode, and may apply any number of cordbg.exe flags at the
”(cordbg)” command prompt
When we finished debugging our application we can exit debugging mode by simply typing exit
or just ex
Ravikiran
30 CHAPTER 2. BUILDING C# APPLICATIONS
1. Click create project link from the start page or by choosing File — New — Project
Menu selection
2. Next, New project Dialog will be appeared which allows us to choose different Project
Types and Templates under the selected Project type.
Ravikiran
2.7. USING VISUAL STUDIO - .NET IDE 31
3. After selecting the appropriate project type and template, specify the name of the project,
location of project and also name of the solution in the corresponding texfields located at
the bottom of New Project Dialog and then click ok button
Ravikiran
32 CHAPTER 2. BUILDING C# APPLICATIONS
Ravikiran
2.8. BUILDING VS.NET TEST APPLICATION 33
1. As project items, which appear under a project folder in Solution Explorer, for example,
forms, source files, and classes.
2. As solution items, which appear in the Solution Items folder of Solution Explorer.
3. As miscellaneous files, which are files that are not associated with either a project or a
solution and are displayed in the Miscellaneous Files folder.
Ravikiran
34 CHAPTER 2. BUILDING C# APPLICATIONS
The box provides a number of settings, which map to various flags of the command line compiler.
To begin, when we select the Application tab, we are able to configure the type of output file
that should be produced by csc.exe.
You are also able to configure which item in your application should be marked as the ”Startup
object” (meaning, the class in the application that contains the Main() method). Finally, we can
also allows you to configure the ’default’ namespace for this particular project.
Ravikiran
2.10. OTHER KEY ASPECTS OF VS.NET IDE 35
Another important aspect of the IDE is the Properties window. This window allows you to
interact with a number of characteristics for the item that has the current focus. This item may
be an open source code file, a GUI widget, or the project itself.
The Server Explorer is a new development tool in Visual Studio .NET or in Visual Studio 2005
that is shared across development languages and projects. With the Server Explorer, you can
connect to servers, as well as view and access their resources. For example, you can connect to,
view and access the following resources:
1. Database Connections
Ravikiran
36 CHAPTER 2. BUILDING C# APPLICATIONS
2. Servers
3. Crystal Reports
4. Event logs
5. Message Queues
6. Performance Counters
7. Window Services
Ravikiran
2.11. C# LANGUAGE’S PREPROCESSOR DIRECTIVES 37
1. #if : #if lets us 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:
Ravikiran
38 CHAPTER 2. BUILDING C# APPLICATIONS
symbol
The name of the symbol we want to test. we 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 us to 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.
2. #else : #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.
3. #elif
4. #endif
5. #define : #define lets you define a symbol, such that, by using the symbol as the expres-
sion passed to the #if directive, the expression will evaluate to true.
6. #undef : #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.
7. #warning : #warning lets you generate warning from a specific location in your code
where text is the text of the warning that should appear in the compiler’s output.
8. #error : #error lets you generate an error from a specific location in your code where
text is the text of the warning that should appear in the compiler’s output.
9. #line : #line lets you modify the compiler’s line number and (optionally) the file name
output for errors and warnings
#line [ number [”filename”] — hidden — default ]
where number is the number we want to specify for the following line in a source code file.
”filename” (optional) The file name we 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
Ravikiran
2.11. C# LANGUAGE’S PREPROCESSOR DIRECTIVES 39
marks (” ”).
hidden - Hides the successive lines from the debugger until another #line directive is en-
countered.
default - Resets the line numbering in a file.
10. #region #region lets you specify a block of code that we can expand or collapse when
using the outlining feature of the Visual Studio Code Editor.
• Line control - If we use a program to combine or rearrange source files into an interme-
diate file, which is then compiled, you can use line control to inform the compiler of where
each source line originally came from.
• Error and Warning reporting - The directive ’#error’ causes the preprocessor to
report a fatal error and the directive ’#warning’ is like the directive ’#error’, but causes
the preprocessor to issue a warning and continue preprocessing.
#define TEST
using System;
public class MyClass
{
public static void Main()
{
#if (TEST)
Console.WriteLine(”TEST is defined”);
#else
Console.WriteLine(”TEST is not defined”);
#endif
}
}
Ravikiran
40 CHAPTER 2. BUILDING C# APPLICATIONS
output
TEST is defined In other way you can define it at command line. So program will be like this
Example
using System;
public class MyClass
{
public static void Main()
{
#if (TEST)
Console.WriteLine(”TEST is defined”);
#else
Console.WriteLine(”TEST is not defined”);
#endif
}
}
Output
TEST is defined
Ravikiran
2.12. SYSTEM ENVIRONMENT CLASS 41
Ravikiran
42 CHAPTER 2. BUILDING C# APPLICATIONS
Ravikiran
Chapter 3
C# Language Fundamentals
3.1.1 Attributes
Attributes allows us to add custom information to the metadata for a class. It contains informa-
tion about a class such as its name, its fields, and its methods, including their parameters and
types. Metadata is essential to enable the .NET run time to load and use a class. The .NET run
time reads the metadata through a process known as reflection. We can use reflection to access
your own custom class metadata.
3.1.2 Modifiers
Modifiers allow us to control access to the class and to restrict the ability of the class to be
instantiated or to serve as the base of another class. The class modifiers are public, protected,
internal, private, abstract, sealed, and new. Using these modifiers, the following access levels
can be specified:
• protected Access is restricted to the containing class or to classes derived from it.
43
44 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
• protected internal Allow protected or internal access. You can also specify this access
level as internal protected
• abstract The abstract modifier indicates that a class is incomplete and must be extended
by a derived class in order to be instantiated.
• sealed A sealed class can not be extended i.e. it cannot serve as a base class for another
class.
• new The new modifier may be applied only to a nested class or other class member, to
indicate that it hides an inherited member of the same name. Hiding isnt necessarily an
error, but the compiler will issue a warning. You can attach the new modifier to the nested
class to tell the compiler that we are aware of the situation and that everything is okay
Example
using system;
public class ClassAnatomy
{
int i;
ClassAnatomy()
{
i=10;
}
static void Main(string[] args)
{
ClassAnatomy ca=new ClassAnatomy();
Console.WritLine(ca.i);
}
}
• public static void Main(string[] args){}//No Return Type and String argument
Ravikiran
3.2. CONSTRUCTORS 45
• public static int Main(string[] args){} Integer Return type and string argument
There are two common ways to read command line arguments in C#. First, you can override
the Main method with an array of strings, which are command line arguments. For example,
the following code loops through the command line arguments and print them on the console.
However, this is not only the way to read command line arguments. For example, if you do
not want to override the Main method? Or access the command line arguments from non-Main
method of your application, we have to use Environment Class, which has a static method
called GetCommandLineArgs, which returns an array of strings containing the arguments. The
following code reads the command line arguments using Environment.GetCommandLineArgs
method.
In Visual Studio, double-click the Properties icon from Solution Explorer and select the Debug
tab on the left side. From here, specify values using the ”Command line arguments” text box
3.2 Constructors
A constructor is a member that implements the actions required to initialize an instance of a
class. Broadly speaking, it is a method in the class which gets executed when its object is created
i.e. a constructor is invoked when you use the ”new” operator.
Constructors are used for initializing the members of a class whenever an object is created with
the default values for initialization. If a class is not defined with the constructor then the CLR
(Common Language Runtime) will provide an implicit constructor which is called as Default
Constructor. A class can have any number of constructors provided they vary with the number
of arguments that are passed, which is they should have different signatures.
Ravikiran
46 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
• Constructors will be having the same name as that of its containing class
• A class has atleast one constructor also known as default constructor [a constructor without
parameter]
Ravikiran
3.2. CONSTRUCTORS 47
CounterClass.i = 100;
CounterClass.IncrementCount();
System.Console.WriteLine(”Current Value: {0 }”, CounterClass.i);
}
}
Ravikiran
48 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
3.3 System.Console
Represents the standard input, output, and error streams for console applications. This class
cannot be inherited. As its name implies, the Console class encapsulates input, output, and
error stream manipulations for console-based applications. The console is an operating system
window where users interact with the operating system or a text-based console application by
entering text input through the computer keyboard, and reading text output from the computer
terminal. Some of the properties of Console are...
Table 3.1: Console Class Properties that support Read and write operations
Ravikiran
3.3. SYSTEM.CONSOLE 49
using System;
using System.Collections.Generic;
using System.Text;
namespace Environment
{
class Program
{
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.WindowWidth = 50;
Console.Title = ”Ravi kiran Console”;
Console.WriteLine(”Ravi kiran”);
Console.BackgroundColor = ConsoleColor.DarkGray;
Console.WriteLine(”Press any key to get beep sound”);
Console.ReadKey();
Console.Beep();
Console.BufferWidth = 100;
Console.WriteLine(”Press any key to clear the screen”);
Console.ReadKey();
Console.Clear();
Console.WriteLine(”Press any key to reset the screen color”);
Console.ReadKey();
Console.ResetColor();
}
}
}
The first parameter to WriteLine() represents a string literal that contains optional placeholders
designated by {0}, {1}, {2}, and so forth (curly bracket numbering always begins with zero).
Ravikiran
50 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
The remaining parameters to WriteLine() are simply the values to be inserted into the respective
placeholders. It is also permissible for a given placeholder to repeat within a given string. For
example,
The above statement prints ” .NET is simple. .NET is like C++ If we require more elaborate
formatting, each placeholder can optionally contain various format characters either in upper
case or lower case.
Ravikiran
3.3. SYSTEM.CONSOLE 51
Ravikiran
52 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
in the class are initialized to their default values, whereas all other reference types are initialized
to null.
1. Class-Level Scope Variables that are defined at the class level become available to any
non-static method within the class.
2. Method-Level Scope Variables declared within the main code block of a method are
available for use by any other part of the method, including nested code blocks
3. Nested Scope Variables declared within a nested scope are not available to those outside
of their code block
Ravikiran
3.6. MEMBER VARIABLE INITIALIZATION 53
class MemberInitializationDemo
{
int i;
string name;
MemberInitializationDemo()
{
i=9;
}
MemberInitializationDemo(string val)
{
i=9;
name=””;
}
static void Main(string[] args)
{
MemberInitializationDemo m1,m2;
m1=new MemberInitializationDemo();
m2=new MemberInitializationDemo(”Ravi kiran”);
}
}
The main method in the above example contains two objects (m1 and m2) for the class ”Mem-
berInitializationDemo”. When memory is alloted for the object m1, m1.i will be having value
of 9 and m1.name will be having value of empty string where as for m2, m2.i will also hold the
value of 9 but m2.name contains ”Ravi kiran”.
Ravikiran
54 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
value. All value types are derived implicitly from the System.ValueType.
The value types consist of two main categories:
• Numeric types
– Integral Types
– Floating-Point types
– Decimal
• bool
• User defined structs
2. Enumerations
using System;
class ValueAndRefernceTypes
{
int i;
static void Main(string[] args)
{
int temp=10;
ValueAndRefernceTypes v=new ValueAndRefernceTypes();
int temp1=temp;
Ravikiran
3.8. BOXING AND UNBOXING 55
ValueAndRefernceTypes v1=v;
temp1=50;
v1.i=100;
Console.WriteLine(”Temp value is {0}”,temp);
Console.WriteLine(”Temp1 value is {0}”,temp1);
}
}
3.8.1 Boxing
Converting a value type to reference type is called Boxing. When the CLR boxes a value type,
it wraps the value inside a System.Object and stores it on the managed heap.In the following
example, the integer variable i is boxed and assigned to object o.
int i=10;
object o = (object) i; //boxing
Boxing is used to store value types in the garbage-collected heap. Boxing is an implicit conversion
of a value type to the type object or to any interface type implemented by this value type. Boxing
a value type allocates an object instance on the heap and copies the value into the new object.
The following statement implicitly applies boxing operation on variable i
int i=10;
object o = i; //implicit boxing
Ravikiran
56 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
3.8.2 UnBoxing
Unboxing is the opposite operation to boxing. An unboxing conversion permits an explicit
conversion from reference type to any value-type. An unboxing operation consists of
1. Checking the object instance to make sure it is a boxed value of the given value type
2. Copying the value from the instance into the value-type variable
When an object box is cast back to its original value type, the value is copied out of the box and
into the appropriate storage location
3.9 System.Object
In C# the Object class is the ultimate base class of every type that all other other types directly
or indirectly derive from it. the object classThe Object class provides a number of methods that
can be called on all objects
1. Equals The Equals method of the object class provides a default implementation that
compares two reference type objects for reference equality. Reference equality occurs when
two reference type objects refer to the same object.
Ravikiran
3.9. SYSTEM.OBJECT 57
using System;
class Program
{
int i;
Program(int j)
{
j = i;
}
void display()
{
Console.WriteLine(”Value of I is ” + i);
}
In above example p and p1 are two different objects (i.e. both of these objects ae pointing
to different memory location), so p.Equals(p1) will returns false. But, the objects p2 and
p are pointing to the same memory location and hence p.Equals(p2) will returns true.
Some times it is necessary to check whether the two objects have same values for their fields
instead of checking for their memory address. So for this purpose, we have to override the
Equals method. For example, if we include the following code in the above example, the
Equlas method will return true if both objects will have the same value for i. (Even though
both objects refer to different memory locations, if the value of i is same it will returns
true or else false)
2. ReferenceEquals In the object class, the Equals and ReferenceEquals methods are se-
mantically equivalent, except that the ReferenceEquals works only on object instances.
Ravikiran
58 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
Object.ReferenceEquals(p,p1)
If both p and p1 refer to same memory location, then it will returns true else it will return
false.
3. GetType GetType is the basis for using reflection in .NET. It returns a Type object,
describing the object it was called on. The GetType method is also useful if we get an
object at runtime and we don’t know what it’s type is. For example
Console.WriteLine(p.GetType())
The above statement will prints the name of the Type (Here it is ”Program”).
4. GetHashCode The GetHashCode method makes any object usable in a Hashtable or any
hashing algorithm. Since the default algorithm supplied by the GetHashCode method of
the object class is not guaranteed to be unique, you should override GetHashCode in your
custom types. For example
Console.WriteLine(p.GetHashCode())
The above line will prints the hash code of object ”p”
5. ToString The purpose of the ToString method is to return a human readable represen-
tation of a type. The default implementation in the object class returns a string with the
name of the runtime type of the object. For example
Console.WriteLine(p)
The above line will prints the name of Type. Here it is ”Program”. The ToString method
is a virtual method, and so we can override this method to return our own string. For
example
6. MemberwiseClone Whenever we need to create a shallow copy of our type, we use the
MemberwiseClone method. A shallow copy is a bitwise copy of our type. As such, if we
perform a MemberwiseClone on our class, it will make a copy of the type and all contained
value types and references types. Since the MemberwiseClone method is not virtual, we
can not override it in derived classes. For example..
Ravikiran
3.10. CONSTANT DATA 59
Program p3=(Program)p.MemberWiseClose();
The above statement will creates a new object p3 exactly of type p. But p and p3 will
point to different memory locations (It is not similar to Program p3=p where p3 and p will
refer to same memory location). As MemberwiseClone returns object, we have to convert
explicitly to the type of object we are going to convert.
Constants are declared with the const modifier. Only the C# built-in types (excluding Sys-
tem.Object) may be declared as const. C# does not support const methods, properties, or
events. Constants can be marked as public, private, protected, internal, or protected internal.
These access modifiers define how users of the class can access the constant. Constants are ac-
cessed as if they were static fields because the value of the constant is the same for all instances
of the type. we do not use the static keyword to declare them.
using System;
class Program
{
const int PI=3.14; //By default const variables are static
static void Main(string[] args)
{
Console.WriteLine(Program.PI);
}
}
Ravikiran
60 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
using System;
class ConstantDemo
{
readonly int A=10;
readonly int B;
readonly int C;
ConstantDemo()
{
B=20;
C=Console.ReadLine();
}
}
• Like constant members, readonly members are not implicitly static, and therefore the static
keyword can be applied to a readonly field explicitly if required.
• A readonly member can hold a complex object by using the new keyword at initialization.
• while
• do-while
• for
• foreach
Ravikiran
3.11. ITERATION CONSTRUCTS IN C# 61
int a=1;
while(a <4)
{
Console.WriteLine(a);
a++;
}
int a=4;
do
{
Console.WriteLine(a);
}while(a <3);
Ravikiran
62 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
int[] a=1,2,3;
foreach(int b in a)
{
Console.WriteLine(b);
}
The main drawback of ’foreach’ loops is that each value extracted (held in the given example by
the variable ’b’) is read-only.
• Jump Statements
• Selection Statements
• break
• continue
• goto
• return
• throw
break
The ’break’ statement breaks out of the ’while’ and ’for’ loops and the ’switch’ statements. The
output of the following loop is the numbers from 0 to 4.
Ravikiran
3.12. FLOW CONTROL STATEMENTS IN C# 63
int i=0;
while(true)
{
Console.WriteLine(i);
if(i==5)
break;
i++;
}
continue
The ’continue’ statement can be placed in any loop structure. When it executes, it moves the
program counter immediately to the next iteration of the loop. The following code example uses
the ’continue’ statement to count the number of values between 1 and 100 inclusive that are not
multiples of seven. At the end of the loop the variable y holds the required value.
int y=0;
for(int x=1;x <101;x++)
{
if((x%7)==0)
continue;
y++;
}
goto
The ’goto’ statement is used to make a jump to a particular labelled part of the program code.
We can use a ’goto’ statement to construct a loop, as in the following example (but again, this
usage is not recommended):
int a=0;
start:
Console.WriteLine(a);
a++;
if(a <5 )
goto start;
Return Statement
The ’return’ statement is used in the method to return some value to the calling part of the
program. When the return statement is encountered in the method, method will stop and return
a value. The control will be transfered to the calling part of the program and starts executes the
statements thereafter.
Ravikiran
64 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
throw statement
Throw statement is used for handling exceptions. Throw statement is used in the try block. When
throw statement is encountered in the middle of try block, then the control will be transferred
to the appropriate catch block.
if(a==10)
Console.WriteLine(” A is equal to 10”);
else
Console.WriteLine(”A is not equal to 10”);
• simple if
• if-else statements
• Nested if statements
• Ladder if-else statements(if-else-if....)
2. Switch statements The switch statements help to control complex conditional and branch-
ing operations. The switch statement transfers control to a statement within its body.
Syntax
switch(expression)
{
case (constantExpression):
//Statements
break;
.
.
.
case (constantExpression):
//Statements
break;
default:
//statements
break
}
Ravikiran
3.13. C# OPERATORS 65
In order to come out of a particular case, we have to use break statement and program
will comes out of the switch body. Without break, the program continues to the next case,
executing the statements until a break or the end of the statement is reached. In some
situations, this continuation may be desirable.
The default statement is executed if no case constant-expression is equal to the value of
switch ( expression ). If the default statement is omitted, and no case match is found,
none of the statements in the switch body are executed. There can be at most one default
statement. The default statement need not come at the end; it can appear anywhere in
the body of the switch statement. A case or default label can only appear inside a switch
statement.
The type of switch expression and case constant-expression must be integral. The value
of each case constant-expression must be unique within the statement body. The case
and default labels of the switch statement body are significant only in the initial test that
determines where execution starts in the statement body. Switch statements can be nested.
3.13 C# Operators
C# provides a large set of operators, which are symbols that specify which operations to perform
in an expression. The following are the C# operators.
• Unary Operators Unary operators are those which will take only one operand. The
various unary operators in C# are
• Binary Operators Binary operators are those which will take two operands.
* , /, % , + , -
• Shift Operators Shift operators are those used to shift bits of a number (in binary
number) towards are right or left
<<, >>
• Relational Operators These operators are used to test the relation of two operands.
• Conditional And This operator returns true if both the expressions on either side of this
operator evaluates to true else it will returns false
Ravikiran
66 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
• Conditional Or This operator returns true if either on of the expressions on either side
of this operator evaluates to true. If both expressions evaluates to false, it will also returns
false.
|| - Logica OR operator
• Assignment operatoars These operators are used to assign values to a variable. The
following are the assignment operators available in C#
1. private : Method that is declared as private can be accessed only by the type in which
the method is defined. (It is the default visiblity level)
2. public : Method that is declared as public can be accessed by any class or object i.e. there
is no restriction in accessing the public method
3. internal : Methods that are declared as internal can be accessed as public by all types
in a containing assembly.
4. protected : Here the access is limited to the containing class or types derived from the
containing class.
5. protected internal : Access is limited to the current assembly or types derived from the
containing class.
Ravikiran
3.16. METHOD PARAMETER MODIFIERS IN C# 67
A static method is callable on a class even when no instance of the class has been created. If
any instances of the class are created, they cannot be used to access the static member. Static
members are often used to represent data or calculations that do not change in response to object
state; for instance, a math library might contain static methods for calculating sine and cosine.
Static class members are declared using the static keyword before the return type of the member,
for example:
static int Sum(int a, int b) return a+b;
Static members are initialized before the static member is accessed for the first time, and before
the static constructor, if any is called. To access a static class member, use the name of the class
instead of a variable name to specify the location of the member.
Static Fields
Static fields can be declared as follows by using the keyword static.
class MyClass
{
public static int x;
public static int y = 20;
}
When we declare a static field inside a class, it can be initialized with a value as shown above.
All un-initialized static fields automatically get initialized to their default values when the class
is loaded first time.
Inside a C# class, member functions can also be declared as static. But a static member function
can access only other static members. They can access non-static members only through an
instance of the class.
We can invoke a static member only through the name of the class. In C#, static members can’t
invoked through an object of the class as like in C++ or JAVA.
we can use any of them with both value and reference types.
Ravikiran
68 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
In the above example, the value of x is not changed in main method even when we call the function
change(). This is because, a new memory is created for the parameter when the function is called
and all the changes will occur in that new memory location and that change is not reflected in
the main method.
So the output of above program will be 10 but not 20.
Ravikiran
3.16. METHOD PARAMETER MODIFIERS IN C# 69
Let’s look at our previous examples, just changing the parameter to be a reference parameter...
• The parameter must be assigned a value before the function member completes normally.
Ravikiran
70 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
The above program will produces 10 and 20 as output. Notice that even though we didnt initialize
the y variable, it will get initiailized in the method. Genrally out parameters are used to return
multiple values from the method.
Parameter arrays allow a variable number of arguments to be passed into a function member.
The definition of the parameter has to include the params modifier, but the use of the parameter
has no such keyword. A parameter array has to come at the end of the list of parameters, and
must be a single-dimensional array. When using the function member, any number of parameters
(including none) may appear in the invocation, so long as the parameters are each compatible
with the type of the parameter array. Alternatively, a single array may be passed, in which case
the parameter acts just as a normal value parameter. For example:
3.17 Arrays in C#
An array is a collection of similar data types stored in adjacent memory locations. Though the
syntax of declaring and using a C# array is more or less similar to that of C/C++, they are
actually created as objects of the System.Array class. Hence arrays in C# fall in the category of
reference types. Like any other reference type, an array object refers to a memory space allocated
on the heap. Following code fragment shows how to declare and initialise an array.
int[] a, b ;
a = new int [10] ;
b = new int [] { 0, 1, 2, 3, 4 } ;
Ravikiran
3.17. ARRAYS IN C# 71
1. BinarySearch This is a static method of System.Array class. It takes two arguments one
is an array type and one is object type. It will searches the array for the given object and
if the object is found it will return the index of that object else it will return the value less
than 0 (negative index). For example
2. Clear : Clear is a static method of Array class. Sets a range of elements in the Array
to zero, to false, or to a null reference depending on the element type. It will take three
parameters -
Ravikiran
72 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
3. Clone : Creates a shallow copy of the Array. The return type of this method is an object.
So we have to use explicitly type cast into the required type. For example..
4. CopyTo : Copies all the elements of the current one-dimensional Array to the specified
one-dimensional Array. It takes two parameters
In the above example, all the elements in a will be copied into b starting at 0th index of b.
5. GetLength Gets a 32-bit integer that represents the number of elements in the specified
dimension of the Array.
6. GetValue :Returns the element at the specified position in an array. For example the
following statement prints element at second index
Console.WriteLine(a.GetValue(2));
7. SetValue :Sets the specified value at the specified position. for example the following
statement sets the value 30 at the position 3.
a.SetValue(30,3);
8. Reverse : Reverses the order of the elements in a one-dimensional. This is static method
and takes one parameter of Array type which has to be reversed.
Ravikiran
3.18. STRING MANIPULATION IN C# 73
9. Sort : Sorts the elements in one-dimensional Array objects. This is static method and
takes one parameter of Array type which has to be sorted.
1. It is a reference type.
2. It’s immutable because its value cannot be modified once it has been created. Methods
that appear to modify a String actually return a new String containing the modification.
1. Trim :It strips all white spaces from both the start and end of the string. string Name =”
String Manipulation ”; string NewName = Name.Trim();
2. Copy : This method simple creates a copy of an existing string. It provides the same
functionality as assigning to a string directly. This is a static method. string sample =
”Ravi kiran.”
string result = string.Copy(sample); //result = ”Ravi kiran.”
3. Compare : It is a static method. Compares two specified String objects and returns an
integer that indicates their relationship to one another in the sort order i.e. if both strings
are equal it will returns 0, else if first string is greater it will returns 1 else it will returns
-1. Example
string s=”ravi”;
string s1=”kiran”;
Console.WriteLine(string.Compare(s,s1)); //Prints 1
5. Contains : Returns a boolean indicating whether the specified String object occurs
within this string. Example
string s=”ravi kiran”;
Console.WriteLine(s.Contains(”avi”)); //Prints true;
Ravikiran
74 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
6. EndsWith : Determines whether the end of a String matches a specified string. Example
string s=”ravi kiran”;
Console.WriteLine(s.EndsWith(”an”)); //Prints true;
7. Format :Replaces each format item in a specified string with the text equivalent of a
corresponding object’s value. Example
Console.WriteLine(string.Format(”{0:c}”,1000)); //Prints$1,000.00;
8. IndexOf :Reports the index of the first occurrence of a String within this string. Example
string s=”Ravi”;
Console.WriteLine(s.IndexOf(”av”)); //Prints 1;
9. Insert :Inserts a specified instance of String at a specified index position in this instance.
Example
string s=”Ravi kiran”;
Console.WriteLine(s.Insert(0,”Bandari ”)); //Prints Bandari Ravi kiran;
10. LastIndexOf : Reports the index position of the last occurrence of a specified Unicode
character or String within this instance.
11. PadLeft :Right-aligns the characters in this instance, padding on the left with spaces or
a specified Unicode character for a specified total length. Example
string s=”Ravi”;
Console.WriteLine(s.padLeft(20,’*’)); //Prints ****************Ravi ;
12. PadRight :Left-aligns the characters in this string, padding on the right with spaces or a
specified Unicode character, for a specified total length. Example
string s=”Ravi”;
Console.WriteLine(s.padRight(20,’*’)); //Prints Ravi**************** ;
13. Replace :Replaces all occurrences of a specified Unicode character or String in this in-
stance, with another specified Unicode character or String. Example
string s=”Ravi kiran”;
Console.WriteLine(s.Replace(”a”,’aa”)); //Prints Raavi kiraan ;
16. ToCharArray : Copies the characters in this instance to a Unicode character array.
Example
string s=”Ravi kiran”;
char[] c=s.ToCharArray();
Ravikiran
3.18. STRING MANIPULATION IN C# 75
1. Append : Appends the string representation of a specified object to the end of this
instance. Example
StringBuilder sb=new StringBuilder(”Ravi”);
sb.Append(”Kiran”);
Console.WriteLine(sb); //Prints Ravi Kiran
2. Insert : Inserts the string representation of a specified object into this instance at a
specified character position. Example
StringBuilder sb=new StringBuilder(”Kiran”);
sb.Insert(0,”Ravi”);
Console.WriteLine(sb); //Prints Ravi Kiran
3. Remove : Removes the specified range of characters from this instance. Example
StringBuilder sb=new StringBuilder(”Ravi Kiran”);
sb.Remove(0,4);
Console.WriteLine(sb); //Prints Kiran
4. Replace : Replaces all occurrences of a specified character or string in this instance with
another specified character or string.
Ravikiran
76 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
The second approach is to use ’verbatim string’ literals. These are defined by enclosing the
required string in the characters @” and ”. To illustrate this, to set the variable ’path’ to the
following value:
C:\My Documents\
we could either escape the back-slash characters string path = ”C:\\My Documents\\”
or use a verbatim string thus:
string path = @”C:\MyDocuments\” Usefully, strings written using the verbatim string syntax
can span multiple lines, and whitespace is preserved. The only character that needs escaping is
the double-quote character, the escape sequence for which is two double-quotes together. For
instance, suppose that you want to set the variable ’text’ to the following value:
the word ”big” contains three letters.
Using the verbatim string syntax, the command would look like this:
string text = @”the word ””big”” contains three letters.”
3.19 Enumerations
An enumeration is a special kind of value type limited to a restricted and unchangeable set of
numerical values. By default, these numerical values are integers, but they can also be longs,
bytes, etc. (any numerical value except char) as will be illustrated below.
When you define an enumeration you provide literals which are then used as constants for their
corresponding values. The following code shows an example of such a definition:
public enum Days
{
Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
}
Note, however, that there are no numerical values specified in the above. Instead, the numerical
values are set up according to the following two rules:
Ravikiran
3.19. ENUMERATIONS 77
2. For any other literal: if it is unassigned, then set its value to one greater than the value of
the preceding literal.
From these two rules, it can be seen that DAYS.Monday will be set to 0, and the values increased
until DAYS.Sunday is set to 6. Note also how we are referring to these values - the values spec-
ified in an enumeration are static, so we have to refer to them in code using the name of the
enumeration: ”DAYS.Monday” rather than just ”Monday”. Furthermore, these values are final
- we can’t change their runtime value.
The following code demonstrates how you can override the default setting which makes the
default values integers. In this example, the enumeration values are set to bytes.
public enum Days:byte
{
Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
}
You can also override the default numerical values of any and all of the enumeration elements.
In the following example, the first literal is set to value 1. The other literals are then set up
according to the second rule given above, so DAYS.Sunday will end up equal to 7.
public enum Days:byte
{
Sunday=1,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
}
1. Format :Converts the specified value of a specified enumerated type to its equivalent string
representation according to the specified format It takes three paramters
(a) ”G” or ”g” : If value is equal to a named enumerated constant, the name of
that constant is returned; otherwise, the decimal equivalent of value is returned.
For example, suppose the only enumerated constant is named, Red, and its value
is 1. If value is specified as 1, then this format returns ”Red”. However, if value
is specified as 2, this format returns ”2”.
Ravikiran
78 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
Example
class EnumDemo
{
public enum Days
{
sunday, monday, tuesday
}
2. GetName :Retrieves the name of the constant of the specified enumeration type that has
the specified value. It takes two parameters
enumType : A Type that specifies the type of the enumeration.
value : A Object that contains the integral value or the name of an enumeration constant.
Example
Console.WriteLine(Enum.GetName(typeof(Days),d)); //Prints monday
3. GetNames :Returns a zero-based, one-dimensional String array that contains the names
of the constants of the specified enumeration type. Example
string str[]=Enum.GetNames(typeof(Days));
Ravikiran
3.19. ENUMERATIONS 79
7. IsDefined :Returns a Boolean indicating whether a constant with the specified value exists
in the specified enumeration type. It takes two parameters
enumType - A Type that describes an enumeration.
value - The constant or value being searched for in enumType.
Example
Console.WriteLine(Enum.IsDefined(typeof(Days),1)); //Prints true
Ravikiran
80 CHAPTER 3. C# LANGUAGE FUNDAMENTALS
Ravikiran
Chapter 4
• The properties of normal student like Student ID, Student N ame, Date Of Birth, F ather N ame
etc...
• The functionalities or behaviors of any normal student like Get M arks, Calculate Average
etc...
When we declare a variable in a class we call it member variables or instance variables. The
name instance come from the fact that when we create an object we instance a class to create
that object so instance of a class means object of that class and instance variable means variable
that exists in that class.
81
82 CHAPTER 4. OBJECT ORIENTED PROGRAMMING USING C#
4.1.1 Constructors
A class will also contains Constructors which will be automatically executed when an object of a
class is created. Constructors can be considered as a special class member functions that provide
a simple way to create an instance of a class with inital look and feel (.i.e. all the variables in
a class will be initialized to their default values when object is created). If we didnt declare
any constructor in a class, the compiler will provide one default constructor(Constructor with
no parameters). The role of default constructor is to ensure that all the data in a class is set to
an initial safe (default) value.
For Example
using System;
class Student
{
string name,sid;
int markstotal;
Student(string na,string id,int marks)
{
name=na;
sid=id;
markstotal=marks;
}
void setStudent(string na,string id,int marks)
{
name=na;
sid=id;
markstotal=marks;
}
void displayData(string na,string id,int marks)
{
name=na;
sid=id;
markstotal=marks;
}
}
In the above example there is no default constructor. So, if we want to create an object for the
above class, it is cumpolsory that we have to pass arguments the arguments to an object. Example
Ravikiran
4.2. SELF REFERENCE IN C# 83
As there is parameterized constructor, the compiler will not include any default constructor.
So in order to make above statement correct we have to explicitly include the follwoing default
constructor.
Student()
{
}
It is an error to refer to this in a static method because they exist at the class level and not as
part of an object.
class Student
{
string sid;
int marks;
Student(string s, int i)
{
sid = s;
¿ marks = i;
}
Student():this(”Ravi kiran”, 100)
{
}
void display()
Ravikiran
84 CHAPTER 4. OBJECT ORIENTED PROGRAMMING USING C#
{
Console.WriteLine(”Student ID {0 } /Marks {1 }”, sid, marks);
}
static void Main(string[] args)
{
Student s = new Student();
s.display();
}
} Output
Student ID Ravi kiran
Marks 100
1. Methods : These are member functions that provide some behavior to a class in which
they are declared.
2. Properties : These are Accessor and Mutator Functions which are used to access or set
the values to the class fields.
3. Public fields or Public Variables :These are the fields declared in a class as public.
(Declaring public variables in a class is not recommended)
By default, if we do not explicitly mark the visibility level of a class, it is implicitly set to
”internal”. Internal classes can only be created by types which are present within the same
assembly, and are not accessible from outside the assembly.
1. Encapsulation
2. Inheritance
3. Polymorphism
Ravikiran
4.4. PILLARS OF OOP 85
4.4.1 Encapsulation
Encapsulation is the procedure of covering up of data and functions into a single unit (called
class). An encapsulated object is often called an abstract data type.
2. Encapsulation is a process of hiding all the internal details of an object from the outside
world
3. Encapsulation is the ability to hide its data and methods from outside the world and only
expose data and methods that are required
5. Encapsulation gives you the ability to validate the values before the object user change or
obtain the value
6. Encapsulation makes implementation inaccessible to other parts of the program and protect
from whatever actions might be taken outside the function or class.
The need of encapsulation is to protect or prevent the code (data) from accidental corruption. In
Object oriented programming data is treated as a critical element in the program development
and data is packed closely to the functions that operate on it and protects it from accidental
modification from outside functions.
Rather than defining the data in the form of public, we can declare those fields as private.
The Private data are manipulated indirectly by two ways. The first method is using a pair of
conventional accessor and mutator methods. Another method is using a named property.
Ravikiran
86 CHAPTER 4. OBJECT ORIENTED PROGRAMMING USING C#
In this example employeeid and salary is private fields and providing access to the fields using
public methods (SetEmployeeID,GetEmployeeID,SetSalary,GetSalary)
Properties are a new language feature introduced with C#. Properties in C# helps in protect a
field in a class by reading and writing to it. The first method itself is good but Encapsulation
can be accomplished much smoother with properties. Now let’s see an example.
Ravikiran
4.4. PILLARS OF OOP 87
Many programmers tend to design traditional accessor and mutator methods using ”get ” and
”set ” prefixes (e.g., get Name() and set Name()). This naming convention itself is not problem-
atic. However, it is important to understand that C# property is internally represented using
these same prefixes. For example Assume that class Employee type has a private member vari-
able named empSSn to represent an individual’s Social Security Number, which is manipulated
by a property named SSN.
public class Department
{
private string empSSN;
public string SSN
{
get { return empSSN; }
set
{
empSSN=value;
}
}
public string get SSN() { return empSSN;} //ERROR
public void set SSN(string val) { empSSN = val;} //ERROR
}
In the above example there is one property by name SSN. This property internally represented
as get SSN() and set SSN() methods. So, the compiler will generates an error if we explicitly
Ravikiran
88 CHAPTER 4. OBJECT ORIENTED PROGRAMMING USING C#
Properties can be made read-only. This is accomplished by having only a get accessor in the
property implementation. For Example...
}
}
In the above example, the property ”SSN” is having only get accessor but not set mutator. So
we can call SSN as a ”read-only property
You can assign values to, but not read from, a write-only property. A write-only property only
has a set accessor.
}
}
4.5 Inheritance
Inheritance is one of the primary concepts of object-oriented programming. It allows you to
reuse existing code. The relationship between two or more classes is termed as Inheritance in
an Object Oriented Programming language. Normally there will be one class, from which the
other classes may derive. The former class is called as Base class or super class and latter class
is called as derived class. All variables and methods in the base class can be called in the derived
classes, provided they are declared public or protected.
Ravikiran
4.5. INHERITANCE 89
The subclass can add methods and properties or modify the functionality that it has inherited
to provide a more specialised version of the base class. Inheritance comes in two flavors
using System;
public class ParentClass
{
public ParentClass()
{
Console.WriteLine(”Parent Constructor.”);
}
public void print()
{
Console.WriteLine(”I’m a Parent Class.”);
}
}
public class ChildClass : ParentClass
{
public ChildClass()
{
Ravikiran
90 CHAPTER 4. OBJECT ORIENTED PROGRAMMING USING C#
Console.WriteLine(”Child Constructor.”);
}
public static void Main()
{
ChildClass child = new ChildClass();
child.print();
}
}
Output :
Parent Constructor.
Child Constructor.
I’m a Parent Class.
1. Call a method on the base class that has been overridden by another method.
2. Specify which base-class constructor should be called when creating instances of the derived
class.
Ravikiran
4.5. INHERITANCE 91
using System;
class BaseClass
{
public int i;
public BaseClass(int i)
{
this.i = i;
}
}
class DerivedClass:BaseClass
{
new int i = 0;
DerivedClass(int i):base(i)
{
this.i = 100;
}
void display()
{
Console.WriteLine(”Value of Base Class I is {0 }”,base.i);
Console.WriteLine(”Value of Derived Class I is {0 }”,i);
}
static void Main(string[] args)
{
DerivedClass dc = new DerivedClass(10);
dc.display();
}
}
Output
Value of Base Class I is 10
Value of Derived Class I is 100
Because classes cannot inherit constructors, a derived class must implement its own constructor
and can only make use of the constructor of its base class by calling it explicitly.
If the base class has an accessible default constructor, the derived constructor is not required
to invoke the base constructor explicitly; instead, the default constructor is called implicitly as
the object is constructed. However, if the base class does not have a default constructor, every
derived constructor must explicitly invoke one of the base class constructors using the ”base”
keyword. The keyword - ”base” identifies the base class for the current object.
Ravikiran
92 CHAPTER 4. OBJECT ORIENTED PROGRAMMING USING C#
using System;
sealed class MyClass
{
public int x;
}
class MainClass
{
public static void Main()
{
MyClass mC = new MyClass();
mC.x = 110;
Console.WriteLine(”x = {0} ”, mC.x,);
}}
In the preceding example, if we attempt to inherit from the sealed class by using a statement like this:
class MainClass: MyClass {} //Error
You will get the error message:
’MainClass’ cannot inherit from sealed class ’MyClass’.
Sealed Methods in C#
using System;
sealed class MyClass
{
public void virtual Display()
{
Console.WriteLine(”Virtual Method”);
}
}
Ravikiran
4.6. PLOYMORPHISM 93
4.6 Ploymorphism
Through inheritance, a class can be used as more than one type; it can be used as its own type,
any base types, or any interface type if it implements interfaces. This is called polymorphism.
In C#, every type is polymorphic. Types can be used as their own type or as a Object instance,
because any type automatically treats Object as a base type.
When a derived class inherits from a base class, it gains all the methods, fields, properties and
events of the base class. To change the data and behavior of a base class, we have two choices:
we can replace the base member with a new derived member, or we can override a virtual base
member.
Replacing a member of a base class with a new derived member requires the new keyword. If a
base class defines a method, field, or property, the new keyword is used to create a new definition
of that method, field, or property on a derived class. The new keyword is placed before the return
type of a class member that is being replaced. For example
Ravikiran
94 CHAPTER 4. OBJECT ORIENTED PROGRAMMING USING C#
When the new keyword is used, the new class members are called instead of the base class
members that have been replaced. Those base class members are called hidden members. Hidden
class members can still be called if an instance of the derived class is cast to an instance of the
base class.
In order for an instance of a derived class to completely take over a class member from a base
class, the base class has to declare that member as virtual. This is accomplished by adding the
virtual keyword before the return type of the member. A derived class then has the option of
using the override keyword, instead of new, to replace the base class implementation with its
own.
Ravikiran
4.7. ABSTRACT CLASSES & ABSTRACT METHODS 95
{
DerivedClas d=new DerivedClasb();
d.display(); //Prints Derived Class
BaseClass b=(BaseClass)d; //Prints Derived Class
b.display();
}
}
Fields cannot be virtual; only methods, properties, events and indexers can be virtual. When a
derived class overrides a virtual member, that member is called even when an instance of that
class is being accessed as an instance of the base class.
An abstract class cannot be instantiated. The purpose of an abstract class is to provide a com-
mon definition of a base class that multiple derived classes can share.
Abstract classes normally contain one or more abstract methods or abstract properties, such
methods or properties do not provide implementations, but derived classes must override inher-
ited abstract methods or properties.
Abstract classes may also define abstract methods. This is accomplished by adding the keyword
abstract before the return type of the method. For example:
Ravikiran
96 CHAPTER 4. OBJECT ORIENTED PROGRAMMING USING C#
However, the following is illegal, because the compiler cannot provide an implicit downcast:
2. type : A type.
The ”is” operator checks whether an object is compatible with a given type, and the result of
the evaluation is a Boolean: true or false. The is operator will never throw an exception. The
follwoing code demonstrates
Ravikiran
4.8. TYPE CASTING IN C# 97
If the object reference is null, the is operator always returns false because there is no object
available to check its type.
Implicit casting occurs if the target variable is of a compatible type that is higher in the inher-
itance hierarchy (a superclass), or is of an interface that is implemented by the object’s class,
either directly or indirectly. In these cases, no additional work is required of the developer; the
conversion happens automatically.
Explicit casting must be used when the conversion is in the opposite direction to that required
by implicit casting. For example, when casting an object to one of its subclasses or casting from
an interface to a class. To perform explicit casting, the cast operator is used.
In the following example code, we can see a variable being cast from a subclass to its superclass
using implicit casting. It is then returned to the subclass using explicit casting.
Explicit casting is useful but can be problematic when the variable being cast is not compatible
with the target type. In this situation an exception is thrown.
C# includes another method of performing explicit conversions. Using the ”as” operator, an
object can be converted from one type to another. Unlike with explicit casting, if the conversion
is not possible because the types are incompatible the operation does not throw an exception.
Ravikiran
98 CHAPTER 4. OBJECT ORIENTED PROGRAMMING USING C#
class Student
{
void display()
{
Console.WriteLine(”This is Student Class”);
}
static void Main(string[] args)
{
Object o=new Object();
Student s=(Student) o; //ERROR - Invalid Cast, generates Compile Error
Student s1=o as Student; //VALID statement but here s1 will be assigned to null
}
}
Ravikiran
Chapter 5
• Bugs : A software bug is the common term used to describe an error, flaw, mistake, failure,
or fault in a computer program or system that produces an incorrect or unexpected result,
or causes it to behave in unintended ways.
• Errors : Unlike bugs, errors are typically caused by the end user of the application, rather
than those who created the appliation. For example, User may enter character data where
numeric data is expected
99
100 CHAPTER 5. EXCEPTIONS AND OBJECT LIFETIME
This way of error handling is called as a classic C approach and it doesn’t provide any helpful
information regarding how to deal with the problem.
So there must be some way to wrap the name, message, and other helpful information regarding
this error condition into single well defined package. This technique of bundling all information
regarding the error is called as structured exception handling.
Exception handling is an in built mechanism in .NET framework to detect and handle run time
errors which can be caused due to logic or system errors. If a user (programmer) do not provide
a mechanism to handle these anomalies, the .NET run time environment provide a default
mechanism, which terminates the program execution.
Another important feature of Exceptions in .NET is that rather than using of numeric constants
for identifying the problem, we are using the exceptions as objects that contain human readable
description of the problem as well as the detailed infromration of the call stack that triggered
the exception in the first place.
• A class type that represents the details of the exception that occurred
• A block of code(try block) on the callers side that invokes the exception-prone
member
• A block of code on the callers side that will process (or catch) the exception
should it occur
Ravikiran
5.3. THE SYSTEM.EXCEPTION BASE CLASS 101
• HelpLink : Gets or sets a link to the help file associated with this exception. This
property returns a URL to a help file describing the error in full detail. For example,
the HelpLink value could be:
”file:///C:/Ravi/help.html”
• Innter Exception : This read-only property can be used to obtain information about
the previous exception(s) that caused the current exception to occur. The previous
exception(s) are recorded by passing them into the constructor of the most current
exception. For Example
try
{
throw new ApplicationException(”This is Application Error”);
}
catch (Exception e)
{
throw new DivideByZeroException(”This is Divide By Zero”,e);
}
• Message :This read-only property returns the textual description of a given error.
The value of the Message property is included in the information returned by ToString.
The Message property is set only when creating an Exception. If no message was
supplied to the constructor for the current instance, the system supplies a default
message that is formatted using the current system culture. For Example
catch (Exception e)
{
Console.WriteLine(e.Message);
}
• Source :This property returns the name of the assembly that threw the exception.
• StackTrace :This read-only property contains a string that identifies the sequence
of calls that triggered the exception. This property is very helpful at the time of
debugging.
The execution stack keeps track of all the methods that are in execution at a given
Ravikiran
102 CHAPTER 5. EXCEPTIONS AND OBJECT LIFETIME
instant. A trace of the method calls is called a stack trace. The stack trace listing
provides a means to follow the call sequence to the line number in the method where
the exception occurs.
class ExceptionDemo
{
static void Main(string[] args)
{
// Check that a parameter was provided
if (args.Length == 0)
{
throw new Exception(”Invalid Arguments”);
}
Console.WriteLine(”{0} argument(s) provided”, args.Length);
}
}
When executed correctly with a parameter, the above program runs without error and outputs
the number of parameters detected. However, if the number of arguments used is zero, this is
identified by the if statement and an exception is thrown. This avoids unexpected exceptions
occurring later due to the parameters being invalid.
Ravikiran
5.5. CATCING EXCEPTIONS 103
The above example works well as long as we dont pass zero as second parameter to Excep-
tion.Divide method. But if we pass zero the program will abnormally terminate as we can’t
divide by zero. The calling the ExceptionDemo.Divide method should be included in a try block
as follows.
try
{
Console.WriteLine(ExceptionDemo.Divide(10, 0));
}
catch(Exception)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.Source);
Console.WriteLine(e.TargetSite);
}
Output
Attempted to divide by zero.
ConsoleApplication1
Double Divide(Int32, Int32)
Even though we passed zero as second argument for ExceptionDemo.Divide Method, the program
will not abnormally terminate. Instead, it will Prints the above output.
Ravikiran
104 CHAPTER 5. EXCEPTIONS AND OBJECT LIFETIME
In some situations, Exceptions may also occur when we call the method that explicitly throws
an Exception. For Example
public class ExceptionDemo
{
private int age;
private string yourName, childName;
string YourName
{
set
{
yourName = value;
}
}
string ChildName
{
set
{
childName = value;
}
}
int Age
{
set
{
if (value <18)
throw new Exception(”Invalid Age”);
else
age = value;
}
}
public void GetData()
{
Console.WriteLine(”Enter Name : ”);
YourName = Console.ReadLine();
try
{
Console.WriteLine(”Enter Name : ”);
YourName = Console.ReadLine();
Console.WriteLine(”Enter Age: ”);
Age = Int32.Parse(Console.ReadLine());
Console.WriteLine(”Enter {0 } Child Name”, yourName);
Ravikiran
5.6. CLR SYSTEM-LEVEL EXCEPTIONS (SYSTEM.SYSTEMEXCEPTION)105
ChildName = Console.ReadLine();
}
catch (Exception)
{
Console.WriteLine(” {0 } is not having Child”, yourName);
}
}
static void Main(String[] args)
{
ExceptionDemo ed = new ExceptionDemo();
ed.GetData();
}
}
In the above example, the Property Age is accepting the values only if we provide value greater
than 18 or else Exception will be thrown. So, when ever we are accessing the Age Property, that
statement should be included in the try-catch block. So, in the GetData method, if we provide
value 18 then only it ask us to enter our ChildName, or else it will print Exception Message.
Ravikiran
106 CHAPTER 5. EXCEPTIONS AND OBJECT LIFETIME
The absolute minimum a new custom exception class needs to have is a name. Lets say we are
designing the login mechanism for a database application and as part of this job we need to
create a custom exception which is thrown if a login attempt fails. A good name for such an
exception would be LoginFailedException. An absolute minimum implementation in C# then
looks like:
Now we can use our custom exception like most other exceptions. We can throw an instance of
LoginFailedException and pass a message which describes the occurred error.
Ravikiran
5.8. HANDLING MULTIPLE EXCEPTIONS 107
But .NET exceptions can do more. we can normally pass a so called inner exception to one of
the constructors which indicates that the created exception is a direct result of a previous one.
This inner exception can then be retrieved via the InnerException property. This way we can
build entire exceptions chains. Since this can be quite useful sometimes, we extend our existing
implementation with this additional constructor.
Ravikiran
108 CHAPTER 5. EXCEPTIONS AND OBJECT LIFETIME
float c = (float)a / b;
Console.WriteLine(” {0} Divided By {1} is {2}”, a, b, c);
}
catch (DivideByZeroException )
{
Console.WriteLine(”You cant Divide a number with Zero”);
}
catch (FormatException)
{
Console.WriteLine(”You have Entered an Invalid Number”);
}
catch (Exception )
{
Console.WriteLine(”Unknown Error”);
}
}
}
Above example includes three catch blocks. The first handles any division by zero error. The
second responds when we enter non numeric string instead on numeric characters. The final
catch block does not specify the type of exception to catch and therefore is executed when any
other type of exception occurs.
Ravikiran
5.10. LAST CHANCE OF EXCEPTION 109
calculated = int.MaxValue;
}
finally
{
Console.WriteLine(”Clearing up any resources.”);
}
}
OUTPUT
Some times it is possible that, we may leave certain runtime anamolies with out handling them.
The result of ignoring an exception would be highly obstructive to the end user of our application,
as an ”unhandled exception” is displayed.
We can generalize our catch blocks in such a way that all our application level exceptions are
handled separately from possible system-level exceptions.
try
{
}
catch(ApplicationException)
{
// All Custom Applications will be caught here
}
catch(SystemException)
{
// All the exceptions thrown by CLR will be caught here
}
Ravikiran
110 CHAPTER 5. EXCEPTIONS AND OBJECT LIFETIME
if we click the ViewDetail link, we will find the details regarding the state of the object
Ravikiran
5.13. UNDERSTANDING OBJECT LIFE TIME 111
Ravikiran
112 CHAPTER 5. EXCEPTIONS AND OBJECT LIFETIME
1. Calculate the total amount of memory required for the object about to be allocated. If the
object contains other internal objects (i.e. the ”has-a” relationship as well as nested type
members), memory for those objects should also be calculated. Also the memory required
for each base class is also taken into account.
2. The CLR then examines the managed heap to ensure that there is enough memory to allo-
cate for the object to be newly created. If there is enough memory, the type’s constructor is
called, and the caller is returned a reference to the type in the memory, which just happens
to be identical to the last position of the new object pointer.
3. Finally, before returning the reference to the caller, the CLR will advance the new object
pointer to point to the next available slot on the managed heap.
If we goes on creating objects, at some point of time the managed heap will become full. When
newobj instruction is encountered, and if CLR determines that managed heap does not have
sufficient memory to allocate the requested type, it will perform a garbage collection in an
attempt to free up memory.
Garbage Collector in .Net is in deterministic which means that we can never be sure when the
garbage collector be invoked. When garbage collection occurs, the runtime will checks for objects
in the managed heap that are no longer being used by the application and performs the necessary
operations to reclaim their memory.
Every application has a set of roots. Roots identify storage locations, which refer to objects on
the managed heap or to objects that are set to null.
For example
Ravikiran
5.15. GARBAGE COLLECTION ALGORITHM 113
Implementation
Garbage collection in .NET is done using tracing collection and specifically the CLR implements
the Mark/Compact collector. This method consists of two phases as described below.
• Phase:1 Mark
Find memory that can be reclaimed.
When the garbage collector starts running, it makes the assumption that all objects in the
heap are garbage. In other words, it assumes that none of the application’s roots refer to
any objects in the heap.
The following steps are included in Phase 1:
Once all the roots have been checked, the garbage collector’s graph contains the set of all
objects that are somehow reachable from the application’s roots; any objects that are not
in the graph are not accessible by the application, and are therefore considered garbage.
• Phase II: Compact Move all the live objects to the bottom of the heap, leaving free
space at the top. Phase II includes the following steps:
1. The garbage collector now walks through the heap linearly, looking for contiguous
blocks of garbage objects
2. The garbage collector then shifts the non-garbage objects down in memory, removing
all of the gaps in the heap
3. Moving the objects in memory invalidates all pointers to the objects. So the garbage
collector modifies the application’s roots so that the pointers point to the objects’ new
locations
4. In addition, if any object contains a pointer to another object, the garbage collector
is responsible for correcting these pointers as well.
5. After all the garbage has been identified, all the non-garbage has been compacted, and
all the non-garbage pointers have been fixed-up, a pointer is positioned just after the
last non-garbage object to indicate the position where the next object can be added.
Ravikiran
114 CHAPTER 5. EXCEPTIONS AND OBJECT LIFETIME
Instead of overrding the Finalize method, we have to make use of (C++ like) destructor to syntax
to achieve the same effect.
Ravikiran
5.18. BUILDING AN AD HOC DESTRUCTION METHOD 115
Its a better way to follow to implement the IDisposable interface for all types that wish to support
an explicit form of resource deallocation. For example
Ravikiran
116 CHAPTER 5. EXCEPTIONS AND OBJECT LIFETIME
}
}
1. Generation 0 Identifies a newly allocated object that has never been marked for collection
2. Generation 1 Identifies an object that has survied a garbage collection sweep (i.e. it was
marked for collection, but was not removed due to the fact that the heap had enough free
space)
Ravikiran
5.20. THE SYSTEM.GC TYPE 117
3. Generation 2 Identifies an object that has survied more than one sweep of the garbage
collector.
Now, when the collection occurs, the Garbage Collector marks and sweeps all generation-0 objects
first. If this results in the required amount of memory, the remaining objects are promted to the
next available generation. If all generation-0 objects have been removed from the heap, but more
memory is still necessary, generation-1 objects are marked and swept, followed (if necessary) by
generation-2 objects. In this way the newer objects (i.e. local variables) are removed quickly
while an older object is assumed to be in use.
• Collect() : Forces the GC to call the Finalize() method for every object on the managed
heap.
• SuppressFinalize() : Sets a flag indicating that a given object should not have its Final-
ize() method called
Example
Ravikiran
118 CHAPTER 5. EXCEPTIONS AND OBJECT LIFETIME
In the above example, the student class is having both C++ style destructor as well as the
IDisposable interface. Here, our Dispose() method has been altered to call GC.SuppressFinalize()
which informs the system that it should no longer call the destructor for the specified object, as
the end user has called Dispose() method.
Ravikiran
Chapter 6
Interfaces describe a group of related functionalities that can belong to any class or struct.
Interfaces can consist of methods, properties, events, indexers, or any combination of those four
member types.
When a class or struct is said to inherit an interface, it means that the class or struct provides
an implementation for all of the members defined by the interface. The interface itself provides
no functionality that a class or struct can inherit in the way that base class functionality can
be inherited. However, if a base class implements an interface, the derived class inherits that
implementation.
Interfaces allow you to truly separate the what from the how. The interface tells you only what the
name, return type, and parameters of the method are. Exactly how the method is implemented
is not a concern of the interface. The interface represents how you want an object to be used,
rather than how it happens to be implemented at a particular moment in time.
Interface Syntax
To declare an interface, we use the interface keyword instead of the class or struct keyword.
Inside the interface, we declare methods exactly as in a class or a struct, except that we never
specify an access modifier (no public, private, or protected access), and we replace the method
body with a semicolon. Here is an example:
interface IEmployee
{
string Name();
}
Interface Restrictions
The interface never contains any implementation. The following restrictions are natural conse-
quences of this
119
120 CHAPTER 6. INTERFACES AND COLLECTIONS
1. we are not allowed any fields in an interface, not even static ones.
3. We cannot supply any access modifier in interfaces. All the methods in an interface are
implicitly public.
interface IEmployee
{
string Name();
}
interface IEmployer
{
int Count();
}
We could the implement these interfaces in the Manager class:
Ravikiran
6.2. CONTRASTING INTERFACES TO ABSTRACT BASE CLASSES 121
}
}
When we implement an interface, we must ensure that each method matches its corresponding
interface method exactly, according to the following guidelines:
2. Any parameters (including ref and out keyword modifiers, although not the params keyword
modifier) match exactly.
3. If there is any difference between the interface definition and its declared implementation,
the class will not compile.
In this approach we can come to know at the comopile time only about the interfaces that the
given class is implemented. But sometimes, we will not able to determine at compile time which
interfaces are supported by a given type. For example, assume that we have an array containg
50 Employe - compatable types only some of them are Employers. So if we attempt to to invoke
the Count method on a type that has not implemented Employer, we will receive a compile time
error. For example
Ravikiran
122 CHAPTER 6. INTERFACES AND COLLECTIONS
Ravikiran
6.3. INVOKING INTERFACE MEMBERS AT OBJECT LEVEL 123
}
}
In the above example, if we try to call e[1].Count() method, we will get an error as e[1] is an
object of type Worker where it will not contain the Count() method. So, in order to avoid such
errors, we have to explicitly convert an object to the interface reference. For example
In the above example, we are explicitly trying to convert manager class to IEmployee interface.
If the object does support this interface, we are then able to access the behavior accordingly.
However if we try to convert an object of type Worker into IEmployer interface reference, we will
get a runtime error when invoke Count() method. When we attempt to access an interface not
supported by a given class using a direct cast, the runtime throws an InvalidCastException. To
recover safely from this excption, we have to catch it. For Example..
try
{
Worker w=new Woker();
IEmployer e=(IEmployer)w;
} catch(InvalidCastException e)
{
Console.WriteLine(”Unable to process your request - Invalid Cast”);
}
The second way we can test for interface support (as well as obtain an interface from an object
reference) is to make use of the ”as” keyword. For example:
There is no need of try/catch block when we are making use of the as keyword, given that if the
reference is not null, we know that we are calling on a valid interface reference.
Ravikiran
124 CHAPTER 6. INTERFACES AND COLLECTIONS
The another way to check the implemented interface for a given type is -”is” keyword. If the
object is not compatiable with the specified interface, we are returned false. On the other hand,
if the type is compatible with the interface, then we can safely call the members without needing
to make use of try/catch logic. For example...
Interfaces as Parameters
As Interfaces are strongly typed entities, we can use them as parameters for constructing the
methods as well as we can return as values from the methods. For example
interface Animal
{
void Move();
}
class Dog : Animal
{
public void Move()
{
Console.Write(”Dog Can Move from one place to another”);
}
static Animal GetAnimal()
{
Animal a=new Dog();
return a;
}
}
class MainClass
{
static void IsMoving( Animal listener )
{
listener.Move();
}
static void Main()
{
Ravikiran
6.4. EXPLICIT INTERFACE IMPLEMENTATION 125
using System;
interface InterfaceOne
{
void Execute();
}
interface InterfaceTwo
{
void Execute();
}
class MyImplementation: InterfaceOne, InterfaceTwo
{
void InterfaceOne.Execute()
{
Console.WriteLine(”InterfaceOne.Execute implementation”);
}
void InterfaceTwo.Execute()
{
Console.WriteLine(”InterfaceTwo.Execute implementation”);
}
}
class MainClass
{
public static void Main()
{
MyImplementation myImplementation = new MyImplementation();
InterfaceOne interfaceOne = (InterfaceOne) MyImplementation;
interfaceOne.Execute();
Ravikiran
126 CHAPTER 6. INTERFACES AND COLLECTIONS
interface IPerson
{
void GetDetails();
}
interface IStudent:Person
{
void CalculateGrade();
}
Now, if a class wished to support each behavior expressed in this interface hierarchy, it would
derive from the nth-most interface (IStudent). Any methods defined by the base interface(s) are
automatically carried into the definition. For example:
class Student:IStudent
{
void GetDetails()
{
}
Ravikiran
6.5. BUILDING INTERFACE HIERARCHIES 127
void CalculateGrade()
{
}
}
interface Getter
{
int GetData();
}
interface Setter
{
void SetData(int x);
}
interface GetterAndSetter : Getter, Setter
{
}
class MyData : GetterAndSetter
{
int data;
public int GetData()
{
return data;
}
public void SetData(int x)
{
data = x;
}
}
class MainClass
{
static void Main()
{
MyData data = new MyData();
data.SetData(5);
Console.WriteLine(”0”, data.GetData());
}
}
We can build interface hierarchies, that derives from Other Interfaces as above
Ravikiran
128 CHAPTER 6. INTERFACES AND COLLECTIONS
Defines methods that convert the value of the implementing reference or value type to a common
language runtime type that has an equivalent value.
This interface provides methods to convert the value of an instance of an implementing type to
a common language runtime type that has an equivalent value. The common language runtime
types are Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double,
Decimal, DateTime, Char, and String.
If there is no meaningful conversion to a common language runtime type, then a particular in-
terface method implementation throws InvalidCastException. For example, if this interface is
implemented on a Boolean type, the implementation of the ToDateTime method throws an ex-
ception because there is no meaningful DateTime equivalent to a Boolean type. For example...
Ravikiran
6.6. ICONVERTIBLE INTERFACE 129
IFormatProvider
If we are building custom type that should be formatted using various locals, we have to imple-
ment IFormatProvider
IConvertible.GetTypeCode()
This method allows us to programmatically determine a value that represents the typecode of
the type which is represented by the following enumeration.
Ravikiran
130 CHAPTER 6. INTERFACES AND COLLECTIONS
{
Boolean, Byte, Char, DateTime, DBNull, Decimal, Double, Empty, Int16,
Int32, Int64, Object, SByte, Single, String, UInt16,UInt32, UInt64
}
Example
public TypeCode IConvertible.GetTypeCode()
{
return TypeCode.Object;
}
class Person
{
string name;
public Person(string name)
{
this.name = name;
}
public void Display()
{
Console.WriteLine(”Person Name : {0 }”,name);
}
}
class People
{
Person[] p;
People()
{
p = new Person[4];
p[0] = new Person(”Bandari”);
p[1] = new Person(”Ravi”);
p[2] = new Person(”Kiran”);
p[3] = new Person(”Kumar”);
}
Ravikiran
6.7. BUILDING CUSTOM ENUMERATOR 131
If we attempt to execute the above code, the compiler would complain that the People class
does not implement the GetEnumerator() method. This method is defined by the IEnumerable
interface.
Thus, to rectify the problem, you may begin by updating the People definition as follows:
GetEnumerator() method returns yet another interface named IEnumerator. IEnumerator can
be obtained from an object to traverse over an internal collection of types. IEnumerator is also
defined in the System.Collections namespace and defines the following three methods
Ravikiran
132 CHAPTER 6. INTERFACES AND COLLECTIONS
Finally, we have to implement MoveNext(), Current, and Reset() for the People type. Here is
one possible implementation of these members:
class Person
{
string name;
public Person(string name)
{
this.name = name;
}
public override string ToString()
{
return string.Format(”Person Name : {0 }”, name);
}
}
class People:IEnumerable,IEnumerator
{
Person[] p;
private int pos = -1;
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
People()
{
p = new Person[4];
p[0] = new Person(”Bandari”);
p[1] = new Person(”Ravi”);
p[2] = new Person(”Kiran”);
p[3] = new Person(”Kumar”);
}
object IEnumerator.Current
{
get { return p[pos]; }
}
Ravikiran
6.8. BUILDING CLONEABLE OBJECTS 133
bool IEnumerator.MoveNext()
{
if (pos <p.Length-1)
{
pos++;
return true;
}
return false;
}
void IEnumerator.Reset()
{
pos = 0;
}
static void Main()
{
People p = new People();
IEnumerator ie = p.GetEnumerator();
while (ie.MoveNext())
{
Person per = (Person)ie.Current;
Console.WriteLine(per);
}
}
}
class Person
{
public string name;
public int age;
Person(string name, int age)
{
this.name = name;
this.age = age;
}
public override string ToString()
Ravikiran
134 CHAPTER 6. INTERFACES AND COLLECTIONS
{
return String.Format(”Name:{0 }\nAge:{1 }”, this.name, this.age);
}
static void Main()
{
Person p1 = new Person(”Ravi”, 28);
Person p2 = p1;
p1.name = ”Kiran”;
Console.WriteLine(p2);
}
}
If we assign one object to another object, only reference will be copied. So if we change the
values of p1 the same will be affected on object p2. When we wish our custom types to return
identical copy of itself to the caller, we have to implement the standard ICloneable interface.
This type defines a single method named Clone().
The basic functionality of Clone() method is to copy the value of our member variables into a
new object instance and return it to the user.
class Person
{
public string name;
public int age;
Person(string name, int age)
{
this.name = name;
this.age = age;
}
public override string ToString()
{
return String.Format(”Name: {0 }\nAge: {1 }”, this.name, this.age);
}
public object Clone()
{
return new Person(this.name,this.age);
}
static void Main()
Ravikiran
6.9. BUILDING COMPARABLE OBJECTS (ICOMPARABLE) 135
{
Person p1 = new Person(”Ravi”, 28);
Person p2 = (Person)p1.Clone();
p1.name = ”Kiran”;
Console.WriteLine(p2);
}
}
In this way, we can create exact copies of the Person type, as illustrated in the above code.
If our type (here Person) did not contain any internal reference types, then we can modify the
Clone() Method as follows
MemberWiseClone() method of object class, will perfom only shallow copy i.e. it will also copy
references of any Internal reference types. If we want to perfom deep copy we need to create a
new instance type and manually assign the inner object reference to new (identical) objects.
using System;
using System.Collections; class Person:IComparable
{
public string name;
public int age;
public int[] arry;
Person(string name, int age)
Ravikiran
136 CHAPTER 6. INTERFACES AND COLLECTIONS
{
this.name = name;
this.age = age;
}
public override string ToString()
{
return String.Format(”Name: {0 }\n Age: {1 }”, this.name, this.age);
}
static void Main()
{
Person[] person = new Person[3];
person[0] = new Person(”Ravi”, 29);
person[1] = new Person(”Bandari”, 28);
person[2] = new Person(”Kiran”,30);
foreach (Person temp in person)
Console.WriteLine(temp);
Array.Sort(person);
Console.WriteLine(”After Sorting...”);
foreach (Person temp in person)
Console.WriteLine(temp);
}
public int CompareTo(object obj)
{
Person temp = (Person)obj;
if (this.age <temp.age)
return -1;
if (this.age >temp.age)
return 1;
return 0;
}
}
Now, in the above program Array.Sort(person) statement sorts the person array based on the
age data member of the person.
interface IComparer
Ravikiran
6.9. BUILDING COMPARABLE OBJECTS (ICOMPARABLE) 137
{
int Compare(object obj1,object obj2);
}
Unlike IComparable interface, IComparer is not implemented on the type we are trying to sort
(here Person). Rather, we implement this interface on any of the helper objects one for each
sort order. Currently, the Person type already knows how to compare itself against other Person
type based on the age type. Therefore to allow the object Person object to sort an an array of
Person types by their name will require an additional helper class that implements the IComparer
interface. Here’s the code
System.Array has a number of overloaded Sort() methods, one that just happens to take an
object implementing IComparer
Ravikiran
138 CHAPTER 6. INTERFACES AND COLLECTIONS
1. ICollection : Defines generic characteristics (eg- read-only, thread safe ) for a collection
class.
7. IHashCodeProvider : Returns the hash code for the Implementing type using a cus-
tomized hash alogrithm
8. IList : Provides a behavior to add, remove, and index items in a list of objects.
Ravikiran
6.10. EXPLORING THE SYSTEM.COLLECTIONS NAMESPACE 139
IDictonaryEnumerator allows us to enumerate over items in the dictionary via the generic Entry
property, which returns a System.Collections.DictionaryEntry class type. In addition, we are
also able to traverse the name/value pairs using the Key/Value properties.
Ravikiran
140 CHAPTER 6. INTERFACES AND COLLECTIONS
The types that implement this interface provides the ability to retrieve the hash code for a particu-
lar type (which may or may not leverage the type’s implementation of System.Object.GetHashCode()).
ArrayList
• You can add an element to the end of an ArrayList by using its Add method. You supply
the element to be added. The ArrayList resizes itself if necessary.
• You can insert an element into the middle of an ArrayList by using its Insert method.
Again, the ArrayList resizes itself if necessary. For example
Ravikiran
6.10. EXPLORING THE SYSTEM.COLLECTIONS NAMESPACE 141
The Queue class implements a first-in first-out (FIFO) mechanism. An element is inserted into
the queue at the back (the enqueue operation) and is removed from the queue at the front (the
dequeue operation). The Queue class contains three methods
1. Dequeue() : Removes and returns the object at the beginning of the Queue
3. Peek() : Returns the object at the beginning of the Queue without removing it
Example
The Stack class implements a last-in first-out (LIFO) mechanism. An element joins the stack at
the top (the push operation) and leaves the stack at the top (the pop operation).
Ravikiran
142 CHAPTER 6. INTERFACES AND COLLECTIONS
The array and ArrayList types provide a way to map an integer index to an element. We provide
an integer index inside square brackets (for example, [4]), and you get back the element at index
4 (which is actually the fifth element). However, sometimes we might want to provide a mapping
where the type you map from is not an int but rather some other type, such as string, double,
or Time. In other languages, this is often called an associative array. The Hashtable class
provides this functionality by internally maintaining two object arrays, one for the keys you’re
mapping from and one for the values you’re mapping to. When you insert a key/value pair into a
Hashtable, it automatically tracks which key belongs to which value, and enables you to retrieve
the value that is associated with a specified key. There are some important consequences of the
design of the Hashtable class:
1. A Hashtable cannot contain duplicate keys. If we call the Add method to add a key that
is already present in the keys array, we will get an exception. We can test whether a
Hashtable already contains a particular key by using the ContainsKey method.
2. When we use a foreach statement to iterate through a Hashtable, you get back a Dictio-
naryEntry. The DictionaryEntry class provides access to the key and value elements in
both arrays through the Key property and the Value properties.
Example
Ravikiran
6.10. EXPLORING THE SYSTEM.COLLECTIONS NAMESPACE 143
{
Console.WriteLine(”Key is {0 }”, element.Key);
Console.WriteLine(”Value is {0 }”,element.Value);
}
}
Ravikiran