csharp handout v1.0

209
Handout: C# Version: C#/Handout/0308/1.0 Date: 10-04-08 Cognizant 500 Glen Pointe Center West Teaneck, NJ 07666 Ph: 201-801-0233 www.cognizant.com

Upload: prathap-katreddy

Post on 22-Apr-2015

295 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: CSharp Handout v1.0

Handout: C# Version: C#/Handout/0308/1.0

Date: 10-04-08

Cognizant

500 Glen Pointe Center West

Teaneck, NJ 07666

Ph: 201-801-0233

www.cognizant.com

Page 2: CSharp Handout v1.0

Handout - C#

Page 2 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

TABLE OF CONTENTS

Introduction ................................................................................................................................... 8 

About this Module ......................................................................................................................... 8 

Target Audience ........................................................................................................................... 8 

Module Objectives ........................................................................................................................ 8 

Pre-requisite ................................................................................................................................. 8 

Session 02: Overview of .NET Framework ................................................................................... 9 

Learning Objectives ...................................................................................................................... 9 

Overview of .Net Framework ........................................................................................................ 9 

Common Language Runtime ........................................................................................................ 9 

CommonTypeSystem ................................................................................................................. 10 

Common Language Specification ............................................................................................... 11 

Assembly .................................................................................................................................... 12 

Application Domains ................................................................................................................... 13 

Runtime Hosts ............................................................................................................................ 14 

Garbage Collection ..................................................................................................................... 15 

Summary .................................................................................................................................... 16 

Test Your Understanding ............................................................................................................ 16 

Session 03: Introduction to C# ................................................................................................... 17 

Learning Objectives .................................................................................................................... 17 

C# Variables, Identifiers and Keywords ..................................................................................... 17 

C# Statements ............................................................................................................................ 18 

Identifiers .................................................................................................................................... 23 

Keywords .................................................................................................................................... 23 

Console Applications .................................................................................................................. 24 

Summary .................................................................................................................................... 25 

Test Your Understanding ............................................................................................................ 25 

Session 05: Data Types and Control Flow ................................................................................. 26 

Learning Objectives .................................................................................................................... 26 

Data Types ................................................................................................................................. 26 

Boxing and UnBoxing ................................................................................................................. 33 

Operators .................................................................................................................................... 35 

Control Flow ................................................................................................................................ 37 

Summary .................................................................................................................................... 44 

Page 3: CSharp Handout v1.0

Handout - C#

Page 3 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Test your Understanding ............................................................................................................ 44 

Session 08: Arrays, Methods and Parameters .......................................................................... 45 

Learning Objectives .................................................................................................................... 45 

Arrays ......................................................................................................................................... 45 

Methods ...................................................................................................................................... 50 

Parameters ................................................................................................................................. 51 

Method Overloading ................................................................................................................... 53 

Summary .................................................................................................................................... 54 

Test your Understanding ............................................................................................................ 54 

Session 11: Creating Value with Enumerations and Structs ................................................... 55 

Learning Objectives .................................................................................................................... 55 

Enumerations .............................................................................................................................. 55 

Structs ......................................................................................................................................... 57 

Summary .................................................................................................................................... 58 

Test your Understanding ............................................................................................................ 58 

Session 12: Classes and Objects ............................................................................................... 59 

Learning Objectives .................................................................................................................... 59 

Fundamentals of object-oriented programming .......................................................................... 59 

Characteristics of an object-oriented language .......................................................................... 60 

Inheritance, Overriding and Overloading .................................................................................... 61 

Polymorphism ............................................................................................................................. 64 

Summary .................................................................................................................................... 66 

Test your Understanding ............................................................................................................ 66 

Session 13: Classes and Objects ............................................................................................... 67 

Learning Objectives .................................................................................................................... 67 

Classes and Objects ................................................................................................................... 67 

Properties ................................................................................................................................... 68 

Indexers ...................................................................................................................................... 69 

Access Modifiers......................................................................................................................... 72 

Summary .................................................................................................................................... 78 

Test your Understanding ............................................................................................................ 78 

Session 14: Classes and Objects ............................................................................................... 79 

Learning Objectives .................................................................................................................... 79 

Static Methods, Variables and Classes ...................................................................................... 79 

Page 4: CSharp Handout v1.0

Handout - C#

Page 4 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Partial Classes ............................................................................................................................ 80 

Nested Classes ........................................................................................................................... 82 

Summary .................................................................................................................................... 83 

Test your Understanding ............................................................................................................ 83 

Session 17: Inheritance and Interface ........................................................................................ 84 

Learning Objectives .................................................................................................................... 84 

Inheritance .................................................................................................................................. 84 

Abstract Class ............................................................................................................................. 85 

Interface ...................................................................................................................................... 86 

Summary .................................................................................................................................... 88 

Test Your Understanding ............................................................................................................ 88 

Session 21: Nunit ......................................................................................................................... 89 

Learning Objectives .................................................................................................................... 89 

Nunit: .......................................................................................................................................... 89 

Summary ..................................................................................................................................102 

Test your Understanding ..........................................................................................................102 

Session 23: Generics and Collections .....................................................................................103 

Learning Objectives ..................................................................................................................103 

Generics ...................................................................................................................................103 

Classes in Generics ..................................................................................................................105 

Summary ..................................................................................................................................111 

Test Your Understanding ..........................................................................................................112 

Session 24: Generics and Collections .....................................................................................113 

Learning Objectives ..................................................................................................................113 

Collections ................................................................................................................................113 

Defining Collections ..................................................................................................................113 

Commonly Used Collection Types ...........................................................................................113 

Creating and manipulating collection .......................................................................................114 

When to use Generics collections ............................................................................................114 

Classes in collections ...............................................................................................................114 

Summary ..................................................................................................................................122 

Test Your Understanding ..........................................................................................................122 

Session 27: Exception Handling ...............................................................................................123 

Learning Objectives ..................................................................................................................123 

Page 5: CSharp Handout v1.0

Handout - C#

Page 5 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Exception handling in C# ..........................................................................................................123 

Throw Statement ......................................................................................................................125 

Finally Statement ......................................................................................................................125 

User Defined Exceptions ..........................................................................................................126 

Exception Type .........................................................................................................................126 

Summary ..................................................................................................................................128 

Test your Understanding ..........................................................................................................129 

Session 30: File Handling ..........................................................................................................130 

Learning Objectives ..................................................................................................................130 

Stream Class ............................................................................................................................130 

Binary Reader ...........................................................................................................................132 

Binary Writer .............................................................................................................................133 

Text Reader ..............................................................................................................................134 

Text Writer ................................................................................................................................136 

File I/O Operations ...................................................................................................................139 

Stream Reader Class ...............................................................................................................139 

Stream Writer Class ................................................................................................................140 

Summary ..................................................................................................................................142 

Test Your Understanding ..........................................................................................................142 

Learning Objectives ..................................................................................................................143 

XML ..........................................................................................................................................143 

XML Document Object Model ...................................................................................................146 

Reading XML with the XmlReader ...........................................................................................149 

Writing XML with the XmlWriter ................................................................................................150 

Summary ..................................................................................................................................152 

Test your Understanding ..........................................................................................................152 

Session 34: Delegates and Events ...........................................................................................153 

Learning Objectives ..................................................................................................................153 

Events and Delegates: .............................................................................................................153 

Summary ..................................................................................................................................160 

Test your Understanding ..........................................................................................................160 

Session 37: Multithreading ........................................................................................................161 

Learning Objectives ..................................................................................................................161 

Multithreading ...........................................................................................................................161 

Thread States: ..........................................................................................................................161 

How Threading Works: .............................................................................................................162 

Page 6: CSharp Handout v1.0

Handout - C#

Page 6 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

The Thread Pool class ..............................................................................................................162 

Multithreading in C# ..................................................................................................................162 

Advantages and Disadvantages of Multithreading ...................................................................164 

Summary ..................................................................................................................................164 

Test Your Understanding ..........................................................................................................165 

Session 40: Reflection and Serialization .................................................................................166 

Learning Objectives ..................................................................................................................166 

Reflection ..................................................................................................................................166 

Summary ..................................................................................................................................169 

Test Your Understanding ..........................................................................................................169 

Session 42: Reflection and Serialization .................................................................................170 

Learning Objectives ..................................................................................................................170 

Overview ...................................................................................................................................170 

What is Serialization and De-serialization? ..............................................................................170 

Working with formatters: ...........................................................................................................173 

Advantages and disadvantages of serialization .......................................................................174 

Summary ..................................................................................................................................174 

Test Your Understanding ..........................................................................................................174 

Session 45: .NET Interoperability .............................................................................................175 

Learning Objectives ..................................................................................................................175 

Overview of .NET and COM interoperability ............................................................................175 

Interoperability through Runtime wrappers ..............................................................................175 

Programming Model comparison of .NET-COM interoperability ..............................................176 

.NET Marshalling ......................................................................................................................177 

Interop marshaler .....................................................................................................................177 

COM Marshaler ........................................................................................................................178 

Summary ..................................................................................................................................178 

Test your Understanding ..........................................................................................................179 

Session 47: Remoting ................................................................................................................180 

Learning Objectives ..................................................................................................................180 

.NET Remoting basics ..............................................................................................................180 

.NET Remoting concepts ..........................................................................................................180 

.NET Remoting Architecture .....................................................................................................183 

Summary ..................................................................................................................................184 

Test your Understanding ..........................................................................................................185 

Page 7: CSharp Handout v1.0

Handout - C#

Page 7 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 48: Remoting ................................................................................................................186 

Learning Objectives ..................................................................................................................186 

Remoting Application: ...............................................................................................................186 

Summary ..................................................................................................................................190 

Test your Understanding ..........................................................................................................190 

Session 50: Garbage Collection and Memory Management ..................................................191 

Learning Objectives ..................................................................................................................191 

Memory Management ...............................................................................................................191 

Allocating Memory ....................................................................................................................191 

Releasing Memory ....................................................................................................................191 

Garbage Collection: ..................................................................................................................193 

Summary ..................................................................................................................................200 

Test your Understanding ..........................................................................................................200 

Glossary ......................................................................................................................................201 

References ..................................................................................................................................208 

Websites ...................................................................................................................................208 

Books ........................................................................................................................................208 

STUDENT NOTES: ......................................................................................................................209 

Page 8: CSharp Handout v1.0

Handout - C#

Page 8 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Introduction

About this Module

This module provides developer with the knowledge and skills that are needed to develop and implement applications using C#.NET.

Target Audience

This module is designed for entry level developers using C# and .NET technologies.

Module Objectives

After completing this module, you will be able to: Describe features of C# Apply .NET Framework technologies like BCL, Remoting, Reflection, and Interop in C# Explain and write C# programs using variables, arrays, operators, and namespaces Write C# programs implementing exceptions handling Describe Object oriented programming in C# Explain threading concept and write multi-threaded programs Explain input output operations in C# Interoperate with legacy COM Define the concepts of Delegates, Events, Reflection, and Remoting

Pre-requisite

Working knowledge in any object oriented programming language and a basic understanding of .NET technologies.

Page 9: CSharp Handout v1.0

Handout - C#

Page 9 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 02: Overview of .NET Framework

Learning Objectives

After completing this session, you will be able to: Describe the .NET Framework Explain Common Language Runtime (CLR), Explain Common Type System (CTS),

and Common Language system (CLS) Explain Assembly and Application Domain Describe Runtime Host and Garbage Collection

Overview of .Net Framework

The .NET Framework is an integral Windows component that supports building and running the next generation of applications and XML Web services. The .NET Framework is designed to fulfill the following objectives:

To provide a consistent object-oriented programming environment whether object code is stored and executed locally, executed locally but Internet-distributed, or executed remotely.

To provide a code-execution environment that minimizes software deployment and versioning conflicts.

To provide a code-execution environment that promotes safe execution of code, including code created by an unknown or semi-trusted third party.

To provide a code-execution environment that eliminates the performance problems of scripted or interpreted environments.

To make the developer experience consistent across widely varying types of applications, such as Windows-based applications and Web-based applications.

To build all communication on industry standards to ensure that code based on the .NET Framework can integrate with any other code.

The .NET Framework has two main components:

Common language runtime .NET Framework class library.

Common Language Runtime

The common language runtime 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.

Page 10: CSharp Handout v1.0

Handout - C#

Page 10 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

For example, you can define a class and then use a different language to derive a class from your original class or call a method on the original class and also pass an instance of a class to a method of a class written in a different language. This cross-language integration is possible because language compilers and tools that target the runtime use a common type system defined by the runtime, and they follow the runtime's rules for defining new types, as well as for creating, using, persisting, and binding to types. Benefits of the CLR are as follows:

Performance improvements. The ability to easily use components developed in other languages. Extensible types provided by a class library.

A CLR feature includes the following:

Cross-language integration, especially cross-language inheritance. Garbage collection, which manages object lifetime so that reference counting is

unnecessary. Self-describing objects, which make using Interface Definition Language (IDL)

unnecessary. The ability to compile once and run on any CPU and operating system that supports

the runtime.

CommonTypeSystem

The common type system defines how types are declared, used, and managed in the runtime, and is also an important part of the runtime's support for cross-language integration. The common type system performs the following functions:

Establishes a framework that helps enable cross-language integration, type safety, and high performance code execution.

Provides an object-oriented model that supports the complete implementation of many programming languages.

Defines rules that languages must follow, which helps ensure that objects written in different languages can interact with each other.

Classification of Types: The common type system supports two general categories of types, each of which is further divided into subcategories:

Value types: Value types directly contain their data, and instances of value types are either allocated on the stack or allocated inline in a structure. Value types can be built-in (implemented by the runtime), user-defined or enumerations

Reference types: Reference types store a reference to the value's memory address, and are allocated on the heap. Reference types can be self-describing types, pointer types, or interface types. The type of a reference type can be determined from values of self-describing types. Self-describing types are further split into arrays and class types. The class types are user-defined classes, boxed value types, and delegates.

Page 11: CSharp Handout v1.0

Handout - C#

Page 11 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

The following example shows the difference between reference types and value types: using System;

class Class1

{

public int Value = 0;

}

class Test

{

static void Main() {

int val1 = 0;

int val2 = val1;

val2 = 123;

Class1 ref1 = new Class1();

Class1 ref2 = ref1;

ref2.Value = 123;

Console.WriteLine("Values: {0}, {1}", val1, val2);

Console.WriteLine("Refs: {0}, {1}", ref1.Value, ref2.Value);

}

}

Type classification:

Common Language Specification

It is a set of basic language features needed by many applications, has been defined. The CLS rules define a subset of the Common Type System. All the rules that apply to the common type system apply to the CLS, except where stricter rules are defined in the CLS.

Page 12: CSharp Handout v1.0

Handout - C#

Page 12 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Assembly

Assemblies are a fundamental part of programming with the .NET Framework. It contains code that the common language runtime executes. Microsoft intermediate language (MSIL) code in a portable executable (PE) file will not be executed if it does not have an associated assembly manifest. Assemblies can be static or dynamic. Static assemblies can include .NET Framework types (interfaces and classes), as well as resources for the assembly (bitmaps, JPEG files, resource files, and so on). Static assemblies are stored on disk in portable executable (PE) files. We can also use the .NET Framework to create dynamic assemblies, which are run directly from memory and are not saved to disk before execution. We can save dynamic assemblies to disk after they have executed. Assembly Benefits:

Assemblies are designed to simplify application deployment It solves versioning problems that can occur with component-based applications It provides the infrastructure to allow multiple versions of a component to be run

simultaneously. Assembly Manifest: Every assembly, whether static or dynamic, contains a collection of data that describes how the elements in the assembly relate to each other. The assembly manifest contains this assembly metadata. The following illustration shows the different ways the manifest can be stored:

For an assembly with one associated file, the manifest is incorporated into the PE file to form a single-file assembly. You can create a multifile assembly with a standalone manifest file or with the manifest incorporated into one of the PE files in the assembly. Each manifest of assembly performs the following functions:

Enumerates the files that make up the assembly. Governs how references to the assembly's types and resources map to the files that

contain their declarations and implementations. Enumerates other assemblies on which the assembly depends.

Page 13: CSharp Handout v1.0

Handout - C#

Page 13 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Provides a level of indirection between consumers of the assembly and the assembly's implementation details.

Renders the assembly self-describing. Assembly Manifest Contents: The following table shows the information contained in the assembly manifest. The first four items—the assembly name, version number, culture, and strong name information—make up the assembly's identity.

Information Description

Assembly name A text string specifying the assembly's name.

Version number A major and minor version number, and a revision and build number. The common language runtime uses these numbers to enforce version policy.

Culture Information on the culture or language the assembly supports. This information should be used only to designate an assembly as a satellite assembly containing culture- or language-specific information. (An assembly with culture information is automatically assumed to be a satellite assembly.)

Strong name information

The public key from the publisher if the assembly has been given a strong name.

List of all files in the assembly

A hash of each file contained in the assembly and a file name. Note that all files that make up the assembly must be in the same directory as the file containing the assembly manifest.

Type reference information

Information used by the runtime to map a type reference to the file that contains its declaration and implementation. This is used for types that are exported from the assembly.

Information on referenced assemblies

A list of other assemblies that are statically referenced by the assembly. Each reference includes the dependent assembly's name, assembly metadata (version, culture, operating system, and so on), and public key, if the assembly is strong named.

Application Domains

Application domains provide a flexible and secure method of isolating running applications. Application domains are usually created and manipulated by run-time hosts. Application domains aid security, separating applications from each other and each other's data. A single process can run several application domains, with the same level of isolation that would exist in separate processes. Running multiple applications within a single process increases server scalability. In the following code example, you create a new application domain and then load and execute a previously built assembly, HelloWorld.exe that is stored on drive C. static void Main()

{

// Create an Application Domain:

System.AppDomain newDomain=

Page 14: CSharp Handout v1.0

Handout - C#

Page 14 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

System.AppDomain.CreateDomain("NewApplicationDomain");

// Load and execute an assembly:

newDomain.ExecuteAssembly(@"c:\HelloWorld.exe");

// Unload the application domain:

System.AppDomain.Unload(newDomain);

}

Application domains have the following properties:

An assembly must be loaded into an application domain before it can be executed. Faults in one application domain cannot affect other code running in another

application domain. Individual applications can be stopped and code unloaded without stopping the entire

process. Cannot unload individual assemblies or types, only entire application domains.

Advantages of Application Domain:

Faults in one application cannot affect other applications. Because type-safe code cannot cause memory faults, using application domains ensures that code running in one domain cannot affect other applications in the process.

Individual applications can be stopped without stopping the entire process. Using application domains enables you to unload the code running in a single application.

Code running in one application cannot directly access code or resources from another application.

The behaviour of code is scoped by the application in which it runs. In other words, the application domain provides configuration settings such as application version policies, the location of any remote assemblies it accesses, and information about where to locate assemblies that are loaded into the domain.

Permissions granted to code can be controlled by the application domain in which the code is running.

Runtime Hosts

The common language runtime has been designed to support a variety of different types of applications from Web server applications to applications with a traditional rich Windows user interface. Each type of application requires a runtime host to start it. The runtime host loads the runtime into a process, creates the application domains within the process, and loads user code into the application domains.

Page 15: CSharp Handout v1.0

Handout - C#

Page 15 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

The .NET Framework ships with a number of different runtime hosts, including the hosts listed in the following table:

Runtime Host Description ASP.NET Loads the runtime into the process that is to handle the Web request.

ASP.NET also creates an application domain for each Web application that will run on a Web server.

Microsoft Internet Explorer

Creates application domains in which to run managed controls. The .NET Framework supports the download and execution of browser-based controls. The runtime interfaces with the extensibility mechanism of Microsoft Internet Explorer through a mime filter to create application domains in which to run the managed controls. By default, one application domain is created for each Web site.

Shell executables

Invokes runtime hosting code to transfer control to the runtime each time an executable is launched from the shell.

Garbage Collection

The .NET Framework's garbage collector manages the allocation and release of memory for your application. Each time you use the new operator to create an object, the runtime allocates memory for the object from the managed heap. As long as address space is available in the managed heap, the runtime continues to allocate space for new objects. However, memory is not infinite. Eventually the garbage collector must perform a collection in order to free some memory. The garbage collector's optimizing engine determines the best time to perform a collection, based upon the allocations being made. When the garbage collector performs a collection, it 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. Automatic memory management is one of the services that the common language runtime provides during Managed Execution. The common language runtime's garbage collector manages the allocation and release of memory for an application. For developers, this means do not have to write code to perform memory management tasks when develop managed applications. Automatic memory management can eliminate common problems, such as forgetting to free an object and causing a memory leak, or attempting to access memory for an object that has already been freed.

Page 16: CSharp Handout v1.0

Handout - C#

Page 16 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Summary

.Net Framework: A common environment for building, deploying, and running Web Services and Web Applications.

Common Language Runtime (CLR): It provides a common runtime for all .NET languages.

Common Type System (CTS): It defines how types are declared, used, and managed in the runtime.

Common Language System (CLS): It specifies the interoperability or the ability to exchange and use information between .NET languages.

Application Domain: It is a logical and physical boundary created around every .NET application by CLR.

Runtime Host: It loads user code into the application domains.

Test Your Understanding

1. What are the components of .Net Framework? 2. What is the purpose of CLR? 3. What are main functions of CLR? 4. What is CTS? 5. What is CLS? 6. What is an Assembly? 7. What is an Application Domain? 8. What is Runtime Host? 9. What are types of Runtime Host in .Net Framework? 10. How many generations are there in GC?

Page 17: CSharp Handout v1.0

Handout - C#

Page 17 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 03: Introduction to C#

Learning Objectives

After completing the session, you will be able to: Define Variables, statements, Identifiers, and Keywords of C# Explain the Console Application of C#

C# Variables, Identifiers and Keywords

Variables represent storage locations. Every variable has a type that determines the values that can be stored in the variable. C# is a type-safe language and the C# compiler guarantees that values stored in variables are always of the appropriate type. C# defines seven categories of variables: static variables, instance variables, array elements, value parameters, reference parameters, output parameters, and local variables. The following sample depicts each of these categories. C# Variables: class A

{

public static int x;

int y;

void F(int[] v, int a, ref int b, out int c) {

int i = 1;

c = a + b++;

}

}

Where x is a static variable: A field declared with the static modifier. A static variable comes into existence before execution of the static constructor for its containing type, and ceases to exist when the associated application domain ceases to exist. y is an instance variable: A field declared without the static modifier is called an instance variable. An instance variable of a class comes into existence when a new instance of that class is created, and ceases to exist when there are no references to that instance and the instance's destructor (if any) has executed. v[0] is an array element: The elements of an array come into existence when an array instance is created, and cease to exist when there are no references to that array instance. a is a value parameter: A parameter declared without a ref or out modifier is a value parameter.

Page 18: CSharp Handout v1.0

Handout - C#

Page 18 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

b is a reference parameter: A parameter declared with an ref modifier is an reference parameter. c is an output parameter: A parameter declared with an out modifier is an output parameter. And finally i is a local variable. A local variable is declared by a local-variable-declaration, which may occur in a block, a for-statement, a switch-statement or a using-statement. The lifetime of a local variable is the portion of program execution during which storage is guaranteed to be reserved for it. The types of the C# language are divided into two main categories: value types and reference types. A third category of types, pointers, is available only in unsafe code. Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store references to their data, the latter being known as objects. With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data and it is not possible for operations on one to affect the other.

C# Statements

Statements are program instructions and they are executed in sequence. C# has the following categories of statements:

S.No Category Purpose C# keywords

1. Selection statements

Causes the program control to be transferred to a specific flow based upon whether a certain condition is true or not.

if, else, switch, case

2. Iteration statements

You can create loops by using the iteration statements. Iteration statements cause embedded statements to be executed a number of times, subject to the loop-termination criteria. These statements are executed in order, except when a jump statement is encountered.

do, for, foreach, in, while

3. Jump statements

Branching is performed using jump statements, which cause an immediate transfer of the program control.

break, continue, default, goto, return, yield

4. Exception handling statements

C# provides built-in support for handling anomalous situations, known as exceptions, which may occur during the execution of your program. These exceptions are handled by code that is outside the normal flow of control.

throw, try-catch, try-finally, try-catch-finally

Page 19: CSharp Handout v1.0

Handout - C#

Page 19 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Category Purpose C# keywords

5. Checked and unchecked

C# statements can execute in either checked or unchecked context. In a checked context, arithmetic overflow raises an exception. In an unchecked context, arithmetic overflow is ignored and the result is truncated. If neither checked nor unchecked is specified, the default context depends on external factors such as compiler options.

checked, unchecked

6. fixed Statement

The fixed statement prevents the garbage collector from relocating a movable variable. The fixed statement is only permitted in an unsafe context. Fixed can also be used to create fixed size buffers.

fixed

7. lock Statement

The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock.

lock

// statements_if_else.cs

// if-else example

using System;

class IfTest

{

static void Main()

{

Console.Write("Enter a character: ");

char c = (char)Console.Read();

if (Char.IsLetter(c))

{

if (Char.IsLower(c))

{

Console.WriteLine("The character is lowercase.");

}

else

{

Console.WriteLine("The character is uppercase.");

}

}

else

{

Console.WriteLine("Not an alphabetic character.");

}

}

}

Page 20: CSharp Handout v1.0

Handout - C#

Page 20 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Iteration statements: // cs_foreach.cs

class ForEachTest

{

static void Main(string[] args)

{

int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };

foreach (int i in fibarray)

{

System.Console.WriteLine(i);

}

}

}

Jump statements: // statements_continue.cs

using System;

class ContinueTest

{

static void Main()

{

for (int i = 1; i <= 10; i++)

{

if (i < 9)

{

continue;

}

Console.WriteLine(i);

}

}

}

Exception handling statements: // try_catch_finally.cs

using System;

public class EHClass

{

static void Main()

{

try

{

Console.WriteLine("Executing the try statement.");

throw new NullReferenceException();

}

Page 21: CSharp Handout v1.0

Handout - C#

Page 21 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

catch (NullReferenceException e)

{

Console.WriteLine("{0} Caught exception #1.", e);

}

catch

{

Console.WriteLine("Caught exception #2.");

}

finally

{

Console.WriteLine("Executing finally block.");

}

}

}

Checked and unchecked: // statements_checked.cs

using System;

class OverFlowTest

{

static short x = 32767; // Max short value

static short y = 32767;

// Using a checked expression

static int CheckedMethod()

{

int z = 0;

try

{

z = checked((short)(x + y));

}

catch (System.OverflowException e)

{

Console.WriteLine(e.ToString());

}

return z;

}

static void Main()

{

Console.WriteLine("Checked output value is: {0}",

CheckedMethod());

}

}

Page 22: CSharp Handout v1.0

Handout - C#

Page 22 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

fixed Statement: // statements_fixed.cs

// compile with: /unsafe

using System;

class Point

{

public int x, y;

}

class FixedTest

{

// Unsafe method: takes a pointer to an int.

unsafe static void SquarePtrParam (int* p)

{

*p *= *p;

}

unsafe static void Main()

{

Point pt = new Point();

pt.x = 5;

pt.y = 6;

// Pin pt in place:

fixed (int* p = &pt.x)

{

SquarePtrParam (p);

}

// pt now unpinned

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

}

}

lock Statement: // statements_lock.cs

using System;

using System.Threading;

class ThreadTest

{

public void RunMe()

{

Console.WriteLine("RunMe called");

}

Page 23: CSharp Handout v1.0

Handout - C#

Page 23 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

static void Main()

{

ThreadTest b = new ThreadTest();

Thread t = new Thread(b.RunMe);

t.Start();

}

}

Identifiers

Identifiers are names used to denote variables, constants, types, methods, objects, and so on. An identifier begins with a letter or an underscore and ends with the character just before the next white space. C# identifiers are case sensitive. For example, the three variables hello, Hello, HELLO, are all different.

using System;

namespace HelloApp

{

class Program

{

static void Main(string[] args)

{

string Hello= "Hello";

string HELLO = "HELLO";

string hello= "hello";

Console.Write("Enter your Name: ");

string name = Console.ReadLine();

Console.WriteLine(Hello+ " " + name);

Console.WriteLine(HELLO + " " + name);

Console.WriteLine(hello + " " + name);

Console.ReadLine();

}

}

}

Keywords

Keywords are predefined reserved identifiers that have special meanings to the compiler. They cannot be used as identifiers in your program unless they include @ as a prefix. For example, @ if is a legal identifier, but if is not because it is a keyword.

Page 24: CSharp Handout v1.0

Handout - C#

Page 24 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

The following table provides the list of keywords in C#:

abstract event new struct

as explicit null switch

base extern object this

bool false operator throw

break finally out true

byte fixed override try

case float params typeof

catch for private uint

char foreach protected ulong

checked goto public unchecked

class if readonly unsafe

const implicit ref ushort

continue in return using

decimal int sbyte virtual

default interface sealed volatile

delegate internal short void

do is sizeof while

double lock stackalloc

else long static

enum namespace string

Console Applications

C# can be used to create applications that take input and display output at the command line console. These applications are ideal for learning C# development because the user interface is so simple. Console applications are also very useful for utility programs that require little or no user interaction. Example: using System;

namespace HelloApp

{

class Program

{

static void Main(string[] args)

{

int intNum1 = 100;

int intNum2 = 200;

int intSum = intNum1 + intNum2;

Console.WriteLine("Sum of two numbers is " + intSum);

Page 25: CSharp Handout v1.0

Handout - C#

Page 25 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Console.ReadLine();

}

}

}

Summary

Statements: o Statements are program instructions. o Statements are executed in sequence.

Identifiers: Identifiers are names used to denote variables, constants, types, methods, objects, and so on.

Keywords: o Keywords are special words built into the C# language and are reserved for

specific use. o Cannot use them for naming your classes, methods, and variables.

Variables: Variables represent storage locations. Every variable has a type that determines the values to be stored in the variable.

Console applications: C# can be used to create applications that take input and display output at the command line console.

Test Your Understanding

1. What are the types of statements and explain its syntax? 2. How do you give valid names in C#? Give some examples. 3. List some of the keywords in C#. 4. What is an Identifier? 5. Can a variable name contain special characters?

Page 26: CSharp Handout v1.0

Handout - C#

Page 26 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 05: Data Types and Control Flow

Learning Objectives

After completing the session, you will be able to: Explain Data Types Explain Boxing and Unboxing Define Operators List various Control Flow Statements

Data Types

C# is a strongly typed language; therefore every variable and object must have a declared type. Some of the data types in C# are explained as follows: Integer: It is denoted by the keyword int.

You can declare and initialize a variable of the type int like this: int intVar=534; Members: Public Fields:

S.No Name Description

1 MaxValue Represents the largest possible value of an Int32. This field is constant.

2 MinValue Represents the smallest possible value of an Int32. This field is constant.

Public Methods:

S.No Name Description

1 CompareTo Overloaded. Compares this instance to a specified object or Int32 and returns an indication of their relative values.

2 Equals Overloaded. Returns a value indicating whether this instance is equal to a specified object or Int32.

3 GetHashCode Overridden. Returns the hash code for this instance.

4 GetType Gets the Type of the current instance. (Inherited from Object.)

5 GetTypeCode Returns the TypeCode for value type Int32.

6 Parse Overloaded. Converts the string representation of a number to its 32-bit signed integer equivalent.

Type Range Size .NET Framework type

int 2,147,483,648 to 2,147,483,647

Signed 32-bit integer System.Int32

Page 27: CSharp Handout v1.0

Handout - C#

Page 27 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

7 ReferenceEquals Determines whether the specified. Object instances are the same instance. (Inherited from Object.)

8 ToString Overloaded. Overridden. Converts the numeric value of this instance to its equivalent string representation.

9 TryParse Overloaded. Converts the string representation of a number to its 32-bit signed integer equivalent. A return value indicates whether the operation succeeded.

Long integer: It is denoted by the keyword long.

You can declare and initialize a long variable like this: long longVar= 4294967296;

Double: The double keyword denotes a simple type that stores 64-bit floating-point values. The following table shows the precision and approximate range for the double type.

You can declare and initialize a double variable like this: double doubleVar=97432.343;

Or double doubleVar=97432.343d;

In the earlier statement, the suffix d is optional. Members: Public Fields:

S.No Name Description

1 MaxValue Represents the largest possible value of a Double. This field is constant.

2 MinValue Represents the smallest possible value of a Double. This field is constant.

3 Epsilon Represents the smallest positive Double greater than zero. This field is constant.

4 NaN Represents a value that is not a number (NaN). This field is constant.

5 NegativeInfinity Represents negative infinity. This field is constant.

6 PositiveInfinity Represents positive infinity. This field is constant.

Type Range Size .NET Framework type

long -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

Signed 64-bit integer

System.Int64

Type Approximate Range Precision .NET Framework type double ±5.0 × 10−324 to ±1.7 × 10308 15-16 digits System. Double

Page 28: CSharp Handout v1.0

Handout - C#

Page 28 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Public Methods:

S.No Name Description

1 CompareTo Overloaded. Compares this instance to a specified object or Double and returns an indication of their relative values.

2 Equals Overloaded. Returns a value indicating whether this instance is equal to a specified object or Double.

3 GetHashCode Overridden. Returns the hash code for this instance.

4 GetType Gets the Type of the current instance. (Inherited from Object.)

5 GetTypeCode Returns the TypeCode for value type Double.

6 IsInfinity Returns a value indicating whether the specified number evaluates to negative or positive infinity

7 IsNaN Returns a value indicating whether the specified number evaluates to a value that is not a number (NaN).

8 IsNegativeInfinity Returns a value indicating whether the specified number evaluates to negative infinity.

9 IsPositiveInfinity Returns a value indicating whether the specified number evaluates to positive infinity.

10 Parse Overloaded. Converts the string representation of a number to its double-precision floating point number equivalent

11 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object)

12 ToString Overloaded. Overridden. Converts the numeric value of this instance to its equivalent string representation.

13 TryParse Overloaded. Converts the string representation of a number to its double-precision floating-point number equivalent. A return value indicates whether the conversion succeeded or failed.

Char: The char keyword is used to declare a Unicode character in the range indicated in the following table. Unicode characters are 16-bit characters used to represent most of the known written languages throughout the world.

You can declare and initialize a char variable like this: char charVar = ’a’;

Members: Public Fields:

S.No Name Description

1 MaxValue Represents the largest possible value of a char. This field is constant.

2 MinValue Represents the smallest possible value of a char. This field is constant.

Type Range Size .NET Framework type Char U+0000 to U+ffff Unicode 16-bit character System.Char

Page 29: CSharp Handout v1.0

Handout - C#

Page 29 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Public Methods:

S.No Name Description

1 CompareTo Overloaded. Compares this instance to a specified object or value type, and returns an indication of their relative values.

2 ConvertFromUtf32 Converts the specified Unicode code point into a UTF-16 encoded string.

3 ConvertUtf32 Overloaded. Converts the value of a UTF-16 encoded surrogate pair into a Unicode code point.

4 Equals Overloaded.

4 GetHashCode Overridden. Returns the hash code for this instance.

5 GetNumericValue Overloaded. Converts a specified numeric Unicode character to a double-precision floating point number.

6 GetType Gets the Type of the current instance. (Inherited from Object)

7 GetTypeCode Returns the TypeCodefor value type Char.

8 GetUnicodeCategory Overloaded. Categorizes a Unicode character into a group identified by one of the UnicodeCategory values.

9 IsControl Overloaded. Indicates whether a specified Unicode character is categorized as a control character.

10 IsDigit Overloaded. Indicates whether a Unicode character is categorized as a decimal digit.

11 IsHighSurrogate Overloaded. Indicates whether the specified Char object is a high surrogate.

12 IsLetter Overloaded. Indicates whether a Unicode character is categorized as an alphabetic letter.

13 IsSurrogatePair Overloaded. Indicates whether two specified Char objects form a surrogate pair.

14 IsSymbol Overloaded. Indicates whether a Unicode character is categorized as a symbol character.

15 IsUpper Overloaded. Indicates whether a Unicode character is categorized as an uppercase letter.

16 IsWhiteSpace Overloaded. Indicates whether a Unicode character is categorized as white space.

17 Parse Converts the value of the specified string to its equivalent Unicode character.

18 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

19 ToLower Overloaded. Converts the value of a Unicode character to its lowercase equivalent.

20 TolowerInvariant Converts the value of a Unicode character to its lowercase equivalent using the casing rules of the invariant culture.

21 ToString Overloaded. Overridden. Converts the value of this instance to its equivalent string representation.

Page 30: CSharp Handout v1.0

Handout - C#

Page 30 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

22 ToUpper Overloaded. Converts the value of a Unicode character to its uppercase equivalent.

23 ToUpperInvariant Converts the value of a Unicode character to its uppercase equivalent using the casing rules of the invariant culture.

24 TryParse Converts the value of the specified string to its equivalent Unicode character. A return code indicates whether the conversion succeeded or failed.

String: The string type represents a string of unicode characters. You can declare and initialize a string variable like this: string strVar=”Welcome”; Members: Public Fields:

S.No Name Description

1 Empty Represents the empty String. This field is read only.

Public Properties:

S.No Name Description

1 Chars Gets the character at a specified character position in this instance.

2 Length Gets the number of characters in this instance.

Public Methods:

S.No Name Description

1 Clone Returns a reference to this instance of String.

2 Compare Overloaded. Compares two specified String objects.

3 CompareOrdinal Overloaded. Compares two String objects by evaluating the numeric values of the corresponding Char objects in each string.

4 CompareTo Overloaded. Compares this instance with a specified object or String and returns an indication of their relative values.

5 Concat . Overloaded. Concatenates one or more instances of String, or the String representations of the values of one or more instances of Object.

6 Contains Returns a value indicating whether the specified String object occurs within this string.

7 Copy Creates a new instance of String with the same value as a specified String.

8 CopyTo Copies a specified number of characters from a specified position in this instance to a specified position in an array of Unicode characters.

Page 31: CSharp Handout v1.0

Handout - C#

Page 31 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

9 EndsWith Overloaded. Determines whether the end of an instance of String matches a specified string.

10 Equals Overloaded. Overridden. Determines whether two String objects have the same value.

11 Format Overloaded. Replaces each format item in a specified String with the text equivalent of a corresponding object's value.

12 GetEnumerator Retrieves an object that can iterate through the individual characters in this string.

13 GetHashCode Overridden. Returns the hash code for this string.

14 GetType Gets the Type of the current instance. (Inherited from Object.)

15 GetTypeCode Returns the TypeCode for class String.

16 IndexOf Overloaded. Reports the index of the first occurrence of a String, or one or more characters, within this string.

17 IndexOfAny Overloaded. Reports the index of the first occurrence in this instance of any character in a specified array of Unicode characters.

18 Insert Inserts a specified instance of String at a specified index position in this instance.

19 Intern Retrieves the system's reference to the specified String.

20 IsInterned Retrieves a reference to a specified String.

21 IsNormalized Overloaded. Indicates whether this string is in a particular Unicode normalization form.

22 IsNullorEmpty Indicates whether the specified String object is a null reference (Nothing in Visual Basic) or an Empty string.

23 Join Overloaded. Concatenates a specified separator String between each element of a specified String array, yielding a single concatenated string.

24 LastIndexOf Overloaded. Reports the index position of the last occurrence of a specified Unicode character or String within this instance.

25 LastIndexOfAny Overloaded. Reports the index position of the last occurrence in this instance of one or more characters specified in a Unicode array.

26 Normalize Overloaded. Returns a new string whose binary representation is in a particular Unicode normalization form.

27 Op_Equality Determines whether two specified String objects have the same value.

28 Op_InEquality Determines whether two specified String objects have different values.

Page 32: CSharp Handout v1.0

Handout - C#

Page 32 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

29 PadLeft Overloaded. Right-aligns the characters in this instance, padding on the left with spaces or a specified Unicode character for a specified total length.

30 PadRight Overloaded. Left-aligns the characters in this string, padding on the right with spaces or a specified Unicode character, for a specified total length.

31 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

32 Remove Overloaded. Deletes a specified number of characters from this instance.

33 Replace Overloaded. Replaces all occurrences of a specified Unicode character or String in this instance, with another specified Unicode character or String.

34 Split Overloaded. Returns a String array containing the substrings in this instance that are delimited by elements of a specified Char or String array.

35 StartsWith Overloaded. Determines whether the beginning of an instance of String matches a specified string.

36 SubString Overloaded. Retrieves a substring from this instance.

37 ToCharArray Overloaded. Copies the characters in this instance to a Unicode character array.

38 ToLower Overloaded. Returns a copy of this String converted to lowercase.

39 ToLowerInvariant Returns a copy of this String object converted to lowercase using the casing rules of the invariant culture.

40 ToString Overloaded. Overridden. Converts the value of this instance to a String.

41 ToUpper Overloaded. Returns a copy of this String converted to uppercase.

42 ToUpperInvariant Returns a copy of this String object converted to uppercase using the casing rules of the invariant culture.

43 Trim Overloaded. Removes all occurrences of a set of specified characters from the beginning and end of this instance.

44 TrimEnd Removes all occurrences of a set of characters specified in an array from the end of this instance.

45 TrimStart Removes all occurrences of a set of characters specified in an array from the beginning of this instance.

Page 33: CSharp Handout v1.0

Handout - C#

Page 33 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Apart from the above primitive data types, C# also provides user-defined value types, enums and structs. Here is a simple example of declaring a value type variable // declares a variable of int type

int iPointX;

bool bChecked = true;

Reference Types Instances of classes are reference types. Reference types are allocated on the heap. In C#, all classes are derived from the .NET Framework class Object within the System namespace. C# does not support pointers directly (though we can use them using unsafe code), but classes, being reference data types, act like pointers. If you copy a pointer to another pointer, then they both still refer the same object. Thus if you pass an instance of a class to a method, changes made to the object passed in will persist upon returning from the method call. As mentioned previously, reference types are allocated on the heap. The new keyword is used to allocate a new instance of a reference type (class).You do not need to free an instance of a class in C#, however. The CLR does garbage collection on object instances that are no longer referenced. Here is a simple example of instantiating an object of a class: // Class is instantiated here using the new keyword. A new object // of type SomeClass will be allocated on the heap. SomeClass instance = new SomeClass();

Boxing and UnBoxing

Boxing and unboxing are the processes that enable value types (for example, integers) to be treated as reference types (objects). The value is "boxed" inside an object and subsequently "unboxed" back to a value type. Boxing Is Implicit Boxing is an implicit conversion of a value type to the type Object. Boxing a value allocates an instance of Object and copies the value into the new object instance. When you provide a value type where a reference is expected and the value is implicitly boxed. For example, if you assign a primitive type such as an integer to a variable of type Object (which is legal because int derives from Object) the value is boxed, int i = 123;

object o = i;

The result of this statement is creating an object o, on the stack, that references a value of the type int, on the heap. This value is a copy of the value-type value assigned to the variable i.

Page 34: CSharp Handout v1.0

Handout - C#

Page 34 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Example: class TestBoxing

{

static void Main()

{

int i = 123;

object o = i; // implicit boxing

i = 456; // change the contents of i

System.Console.WriteLine("The value-type value = {0}", i);

System.Console.WriteLine("The object-type value = {0}", o);

}

}

Unboxing Must Be Explicit Unboxing is an explicit conversion from the type object to a value type or from an interface type to a value type that implements the interface. 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.

The following statements demonstrate both boxing and unboxing operations: int i = 123; // A value type

object box = i; // Boxing

int j = (int)box; // Unboxing

For an unboxing conversion to a given value type to succeed at run time, the value of the source argument must be a reference to an object that was previously created by boxing a value of that value type. If the source argument is null or a reference to an incompatible object, an InvalidCastException is thrown. Example: class TestUnboxing

{

static void Main()

{

int i = 123;

object o = i; // implicit boxing

try

{

int j = (short) o; // attempt to unbox

System.Console.WriteLine("Unboxing OK.");

Page 35: CSharp Handout v1.0

Handout - C#

Page 35 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

}

catch (System.InvalidCastException e)

{

System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message);

}

}

}

Operators

C# has a number of standard operators, taken from C, C++ and Java. Most of these should be quite familiar to programmers and the less common ones are covered here. The operators can be broadly classified as Primary, Unary, Type operators, Arithmetic, Relational, and Logical. The following table lists the standard operators with a syntax sample:

S.No Operator Category Operators

1 Arithmetic + , - , * , / , %

2 Logical & | ^ ! ~ && || true false

3 String Concatenation +

4 Increment, Decrement ++ , --

5 Shift << >>

6 Relational == != < > <= >=

7 Assignment = += -= *= /= %= &= |= ^= <<= >>= ??

8 Member access .

9 Indexing [ ]

10 Cast ()

11 Conditional ?:

12 Delegate Concatenation and

Removal

+ , -

13 Object creation new

14 Type information as , is , Typeof() , sizeof()

16 Indirection and Address

* , -> , [ ] , &

Note that while writing classes it is possible to change the default behavior of some of these operators, although this should only be done where the resultant semantics makes sense. The earlier table also indicates which of the operators are overloadable.

Page 36: CSharp Handout v1.0

Handout - C#

Page 36 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Operator precedence and their associability: When an expression contains multiple operators, the precedence of the operators controls the order in which the individual operators are evaluated. For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the binary + operator. The following table summarizes all operators in order of precedence from highest to lowest:

Category Operators Associability

Primary x.y f(x) a[x] x++ x-- new typeof checked unchecked

Left

Unary + - ! ~ ++x --x (T)x Left

Multiplicative * / % Left

Additive + - Left

Shift << >> Left

Relational and type testing

< > <= >= is as Left

Equality == != Right

Logical AND & Left

Logical XOR ^ Left

Logical OR | Left

Conditional AND && Left

Conditional OR || Left

Conditional ?: Right

Assignment = *= /= %= += -= <<= >>= &= ^= |=

Right

When an operand occurs between two operators with the same precedence, the associability of the operators controls the order in which the operations are performed:

Except for the assignment operators, all binary operators are left-associative, meaning that operations are performed from left to right. For example, x + y + z is evaluated as (x + y) + z.

The assignment operators and the conditional operator (?:) are right-associative, meaning that operations are performed from right to left. For example, x = y = z is evaluated as x = (y = z).

Precedence and associability can be controlled using parentheses. For example, x + y * z first multiplies y by z and then adds the result to x, but (x + y) * z first adds x and y and then multiplies the result by z.

Page 37: CSharp Handout v1.0

Handout - C#

Page 37 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Overloadable Operators: C# allows user-defined types to overload operators by defining static member functions using the operator keyword. Not all operators can be overloaded, however, and others have restrictions, as listed in this table:

S.No Operators Overloadability

1 +, -, !, ~, ++, --, true, false

These unary operators can be overloaded.

2 +, -, *, /, %, &, |, ^, <<, >>

These binary operators can be overloaded.

3 ==, !=, <, >, <=, >=

The comparison operators can be overloaded

4 &&, ||

The conditional logical operators cannot be overloaded, but they are evaluated using & and |, which can be overloaded.

5 [ ] The array indexing operator cannot be overloaded, but you can define indexers.

6 () The cast operator cannot be overloaded, but you can define new conversion operators (see explicit and implicit).

7 +=, -=, *=, /=, %=, &=, |=, ^=,

<<=, >>=

Assignment operators cannot be overloaded, but +=, for example, is evaluated using +, which can be overloaded.

8 =, ., ?:, ->, new, is, sizeof, typeof

These operators cannot be overloaded.

Control Flow

Control flow statements control the execution path of the program. The following table lists the Control flow statements:

S.No Category C# keywords 1 Selection statements if, else, switch, case

2 Iteration statements do, for, foreach,, while

3 Jump statements break, continue, goto, return, throw

Selection Statements--If else: The if statement selects a statement for execution based on the value of a Boolean expression. Example: // statements_if_else.cs

// if-else example

using System;

class IfTest

{

static void Main()

Page 38: CSharp Handout v1.0

Handout - C#

Page 38 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

{

Console.Write("Enter a character: ");

char c = (char)Console.Read();

if (Char.IsLetter(c))

{

if (Char.IsLower(c))

{

Console.WriteLine("The character is lowercase.");

}

else

{

Console.WriteLine("The character is uppercase.");

}

}

else

{

Console.WriteLine("Not an alphabetic character.");

}

}

}

Switch case: The switch statement is a control statement that handles multiple selections and enumerations by passing control to one of the case statements within its body Example: // statements_switch.cs

using System;

class SwitchTest

{

static void Main()

{

Console.WriteLine("Coffee sizes: 1=Small 2=Medium 3=Large");

Console.Write("Please enter your selection: ");

string s = Console.ReadLine();

int n = int.Parse(s);

int cost = 0;

switch(n)

{

case 1:

cost += 25;

break;

case 2:

cost += 25;

Page 39: CSharp Handout v1.0

Handout - C#

Page 39 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

goto case 1;

case 3:

cost += 50;

goto case 1;

default:

Console.WriteLine("Invalid selection. Please select 1, 2, or 3.");

break;

}

if (cost != 0)

{

Console.WriteLine("Please insert {0} cents.", cost);

}

Console.WriteLine("Thank you for your business.");

}

}

Iteration Statements--do: The do statement executes a statement or a block of statements enclosed in {} repeatedly until a specified expression evaluates to false. Example: // statements_do.cs

using System;

public class TestDoWhile

{

public static void Main ()

{

int x = 0;

do

{

Console.WriteLine(x);

x++;

}

while (x < 5);

}

}

for: The for loop executes a statement or a block of statements repeatedly until a specified expression evaluates to false. The for loop is handy for iterating over arrays and for sequential processing. In the following example, the value of int i is written to the console and i is incremented each time through the loop by 1.

Page 40: CSharp Handout v1.0

Handout - C#

Page 40 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Example: // statements_for.cs

// for loop

using System;

class ForLoopTest

{

static void Main()

{

for (int i = 1; i <= 5; i++)

{

Console.WriteLine(i);

}

}

}

foreach; The foreach statement repeats a group of embedded statements for each element in an array or an object collection. The foreach statement is used to iterate through the collection to get the desired information, but should not be used to change the contents of the collection to avoid unpredictable side effects. Example: // cs_foreach.cs

class ForEachTest

{

static void Main(string[] args)

{

int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };

foreach (int i in fibarray)

{

System.Console.WriteLine(i);

}

}

}

while: The while statement executes a statement or a block of statements until a specified expression evaluates to false. Example: // statements_while.cs

using System;

class WhileTest

{

Page 41: CSharp Handout v1.0

Handout - C#

Page 41 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

static void Main()

{

int n = 1;

while (n < 6)

{

Console.WriteLine("Current value of n is {0}", n);

n++;

}

}

}

Jump Statements—break: The break statement terminates the closest enclosing loop or switch statement in which it appears. Control is passed to the statement that follows the terminated statement, if any. Example: // statements_break.cs

using System;

class BreakTest

{

static void Main()

{

for (int i = 1; i <= 100; i++)

{

if (i == 5)

{

break;

}

Console.WriteLine(i);

}

}

}

continue: The continue statement passes control to the next iteration of the enclosing iteration statement in which it appears. Example: // statements_continue.cs

using System;

class ContinueTest

{

static void Main()

{

Page 42: CSharp Handout v1.0

Handout - C#

Page 42 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

for (int i = 1; i <= 10; i++)

{

if (i < 9)

{

continue;

}

Console.WriteLine(i);

}

}

}

goto: The goto statement transfers the program control directly to a labeled statement. Example: // statements_goto_switch.cs

using System;

class SwitchTest

{

static void Main()

{

Console.WriteLine("Coffee sizes: 1=Small 2=Medium 3=Large");

Console.Write("Please enter your selection: ");

string s = Console.ReadLine();

int n = int.Parse(s);

int cost = 0;

switch (n)

{

case 1:

cost += 25;

break;

case 2:

cost += 25;

goto case 1;

case 3:

cost += 50;

goto case 1;

default:

Console.WriteLine("Invalid selection.");

break;

}

if (cost != 0)

{

Page 43: CSharp Handout v1.0

Handout - C#

Page 43 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Console.WriteLine("Please insert {0} cents.", cost);

}

Console.WriteLine("Thank you for your business.");

}

}

return: The return statement terminates execution of the method in which it appears and returns control to the calling method. It can also return an optional value. If the method is a void type, the return statement can be omitted. Example: // statements_return.cs

using System;

class ReturnTest

{

static double CalculateArea(int r)

{

double area = r * r * Math.PI;

return area;

}

static void Main()

{

int radius = 5;

Console.WriteLine("The area is {0:0.00}", CalculateArea(radius));

}

}

throw: The throw statement is used to signal the occurrence of an anomalous situation (exception) during the program execution. Example: // throw example

using System;

public class ThrowTest

{

static void Main()

{

string s = null;

if (s == null)

Page 44: CSharp Handout v1.0

Handout - C#

Page 44 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

{

throw new ArgumentNullException();

}

Console.Write("The string s is null"); // not executed

}

}

Summary

Data types: It is the basic building block of any language. It can be of two types: Build-In Data Type User-Defined Data Type

Boxing: Converting value type to reference type is called Boxing. Following are the two types of boxing:

Implicit Boxing Explicit Boxing

Unboxing: Converting reference type to value type is called Unboxing. Operators: The symbol representing the operations to be performed in an expression. Control Flow Statements: It controls the execution path of the program. It can be of following types:

Selection statements Iteration statements Jump statements

Test your Understanding

1. What are the primitive data types in C#? 2. State the difference between char and string. 3. What is the difference between floating point and decimal type? 4. Differentiate between implicit and explicit casting. 5. What is boxing and unboxing? 6. What are the different types of control flow statements? 7. What is the use of checked and unchecked statements? 8. State the difference between postfix and prefix increment operator.

Page 45: CSharp Handout v1.0

Handout - C#

Page 45 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 08: Arrays, Methods and Parameters

Learning Objectives

After completing this session, you will be able to: Define Arrays and its types Explain Methods and how to call C# methods Identify Parameters and different ways of passing parameters Describe the overview of method overloading

Arrays

An array is an indexed collection of objects, all of the same type. C# arrays are somewhat different from arrays in C++ and other languages—because they are objects. This provides them with built-in support like useful methods and properties. There are three types of arrays:

One-dimensional arrays Multidimensional arrays rectangular arrays, Multidimensional jagged arrays

Declaring an array: C# provides native syntax for the declaration of Array objects: int[] myIntArray;

What is actually created, however, is an object of type System.Array. Arrays in C# thus provide you with the best of both worlds: easy-to-use C-style syntax underpinned with an actual class definition so that instances of an array have access to the methods and properties of System.Array.

Once an array is declared, it must also be instantiated using the new keyword. The following declaration sets aside memory for an array holding five integers: int[] myIntArray = new int[5];

When an array is created for value types, each element initially contains the default value for the type stored in the array. In the earlier example, each of those array elements is initialized to 0, the default value for integer types. With an array of reference types, the elements are not initialized to their default values. Instead, they are initialized to null. Arrays are zero-based, which means that the index of the first element is always zero — in this case, myArray[0]. myIntArray[3]; // return the 4th element

Page 46: CSharp Handout v1.0

Handout - C#

Page 46 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

As arrays are objects, they have properties. One of the more useful properties of the Array class is Length, which tells how many objects are in an array. for (int i = 0;i<5;i++)

{

empArray[i] = i;

}

for (int i = 0;i<empArray.Length;i++)

{

MessageBox.Show(empArray[i]);

}

Initializing Array Elements: Rather than assigning elements to the array as you have done so far, it is possible to initialize the contents of an array at the time it is instantiated by providing a list of values delimited by curly braces ({}). C# provides two different syntaxes to accomplish the same task: int[] myIntArray = new int[5] { 2, 4, 6, 8, 10 };

int[] myIntArray = { 2, 4, 6, 8, 10 };

Multidimensional Rectangular Arrays: A rectangular array is an array of two (or more) dimensions. In the classic two-dimensional array, the first dimension is the number of rows and the second dimension is the number of columns. To declare and instantiate a two-dimensional rectangular array named myRectangularArray that contains two rows and three columns of integers, int [,] myRectangularArray = new int[2,3];

for (int i = 0;i < rows;i++)

{

for (int j = 0;j<columns;j++)

{

rectangularArray[i,j] = i+j;

}

}

The brackets in the int[,] declaration indicate that the type is an array of integers, and the single comma indicates the array has two dimensions; two commas would indicate three dimensions, and so on. Just as you can initialize a one-dimensional array using bracketed lists of values, you can initialize a two-dimensional array using a similar syntax. //this is a 4x3 array (four rows by three columns)

int[,] rectangularArray =

{

{0,1,2}, {3,4,5}, {6,7,8}, {9,10,11}

};

Page 47: CSharp Handout v1.0

Handout - C#

Page 47 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Multidimensional Jagged Arrays: A jagged array is an array of arrays. Specifically, a jagged array is a type of multi-dimensional array in which each row can be a different size from all the other rows. You would declare a two-dimensional jagged array of integers named myJaggedArray as follows: int [] [] myJaggedArray;

To access the fifth element of the third array: myJaggedArray[2][4]

Tip: Notice that when you accessed the members of the rectangular array, you put the indexes all within one set of square brackets: ArrayrectangularArray[row,column]

However, with a jagged array you need a pair of brackets: jaggedArray[row][column]

You can keep this straight by thinking of the first as a single array of more than one dimension and the jagged array as an array of arrays. System.Array: As you say C# implements arrays with the class System.Array. .NET Framework also provides a number of other built-in collection classes, including the ArrayList, Queue, and Stack. The usage of those depends on the requirement of the situation. These can be found in the System.Collections namespace.The following are the members of the Array Class. Public Properties:

S.No. Name Description

1 IsFixedSize Gets a value indicating whether the Array has a fixed size.

2 IsReadOnly Gets a value indicating whether the Array is read-only.

3 IsSynchronized Gets a value indicating whether access to the Array is synchronized (thread safe).

4 Length Gets a 32-bit integer that represents the total number of elements in all the dimensions of the Array.

5 LongLength Gets a 64-bit integer that represents the total number of elements in all the dimensions of the Array.

6 Rank Gets the rank (number of dimensions) of the Array.

7 SyncRoot Gets an object that can be used to synchronize access to the Array.

Page 48: CSharp Handout v1.0

Handout - C#

Page 48 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Public Properties:

S.No. Name Description

1 AsReadOnly Returns a read-only wrapper for the specified array.

2 BinarySearch Overloaded. Searches a one-dimensional sorted Array for a value, using a binary search algorithm.

3 Clear Sets a range of elements in the Array to zero, to false, or to a null reference (Nothing in Visual Basic), depending on the element type.

4 Clone Creates a shallow copy of the Array.

5 ConstrainedCopy Copies a range of elements from an Array starting at the specified source index and pastes them to another Array starting at the specified destination index. Guarantees that all changes are undone if the copy does not succeed completely.

6 ConvertAll Converts an array of one type to an array of another type.

7 Copy Overloaded. Copies a range of elements in one Array to another Array and performs type casting and boxing as required.

8 CopyTo Overloaded. Copies all the elements of the current one-dimensional Array to the specified one-dimensional Array.

9 CreateInstance Overloaded. Initializes a new instance of the Array class.

10 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

11 Exists Determines whether the specified array contains elements that match the conditions defined by the specified predicate.

12 Find Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire Array.

13 FindAll Retrieves all the elements that match the conditions defined by the specified predicate.

14 FindIndex Overloaded.

15 FindLast Searches for an element that matches the conditions defined by the specified predicate, and returns the last occurrence within the entire Array.

16 FindLastIndex Overloaded

17 ForEach Performs the specified action on each element of the specified array.

18 GetEnumerator Returns an IEnumerator for the Array.

19 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

20 GetLength Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

Page 49: CSharp Handout v1.0

Handout - C#

Page 49 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No. Name Description

21 GetLongLenth Gets a 64-bit integer that represents the number of elements in the specified dimension of the Array.

22 GetLowerBound Gets the lower bound of the specified dimension in the Array.

23 GetType Gets the Type of the current instance. (Inherited from Object.)

24 GetUpperBound Gets the upper bound of the specified dimension in the Array.

25 GetValue Overloaded. Gets the value of the specified element in the current Array.

26 IndexOf Overloaded. Returns the index of the first occurrence of a value in a one-dimensional Array or in a portion of the Array.

27 Intialize Initializes every element of the value-type Array by calling the default constructor of the value type.

28 LastIndexOf Overloaded. Returns the index of the last occurrence of a value in a one-dimensional Array or in a portion of the Array.

29 ReferenceEquals Overloaded. Returns the index of the last occurrence of a value in a one-dimensional Array or in a portion of the Array.

30 Resize Changes the size of an array to the specified new size.

31 Reverse Overloaded. Reverses the order of the elements in a one-dimensional Array or in a portion of the Array.

32 SetValue Overloaded. Sets the specified element in the current Array to the specified value.

33 Sort Overloaded. Sorts the elements in one-dimensional Array objects.

34 ToString Returns a String that represents the current Object. (Inherited from Object.)

35 TrueForAll Determines whether every element in the array matches the conditions defined by the specified predicate.

Protected Methods:

S.No. Name Description

1 Finalize Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

2 MemberwiseClone Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

Page 50: CSharp Handout v1.0

Handout - C#

Page 50 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Methods

A method is a code block containing a series of statements. In C#, every executed instruction is done so in the context of a method. Methods are declared within a class or struct by specifying the access level, the return value, the name of the method, and any method parameters. Method parameters are surrounded by parentheses, and separated by commas. Empty parentheses indicate that the method requires no parameters. This class contains three methods: class Motorcycle

{

public void StartEngine() { }

public void AddGas(int gallons) { }

public int Drive(int miles, int speed) { return 0; }

}

Calling the Method: Calling a method on an object is similar to accessing a field. After the object name, add a period, the name of the method, and parentheses. Arguments are listed within the parentheses, and separated by commas. The methods of the Motorcycle class can therefore be called like this: Motorcycle moto = new Motorcycle ();

moto.StartEngine();

moto.AddGas(15);

moto.Drive(5,20);

As shown in the previous code snippet, passing arguments to a method is simply a matter of providing them in the parentheses when calling a method. To the method being called, the incoming arguments are called parameters. The parameters a method receives are also provided in a set of parentheses, but the type and a name for each parameter must be specified. The name does not have to be the same as the argument.

Page 51: CSharp Handout v1.0

Handout - C#

Page 51 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Example: public static void PassesInteger()

{

int fortyFour = 44;

TakesInteger(fortyFour);

}

static void TakesInteger(int i)

{

i = 33;

}

Here a method called PassesInteger passes an argument to a method called TakesInteger. Within PassesInteger, the argument is named fortyFour, but in TakeInteger, this is a parameter named i. This parameter exists only within the TakesInteger method. Any number of other variables can be named i, and they can be of any type, so long as they are not parameters or variables declared inside this method. Notice that TakesInteger assigns a new value to the provided argument. One might expect this change to be reflected in the PassesInteger method once TakeInteger returns, but in fact the value in the variable fortyFour remains unchanged. This is because int is a value type. By default, when a value type is passed to a method, a copy is passed instead of the object itself. As they are copies, any changes made to the parameter have no effect within the calling method. Value types get their name from the fact that a copy of the object is passed instead of the object itself. The value is passed, but not the same object.

Parameters

Parameters are means of passing values to a method. Overloading is the creation of more than one procedure, instance constructor, or property in a class with the same name but different argument types are params, ref, out. Params: The params keyword lets you specify a method parameter that takes an argument where the number of arguments is variable.No additional parameters are permitted after the params keyword in a method declaration, and only one params keyword is permitted in a method declaration. Example: // cs_params.cs

using System;

public class MyClass

{

public static void UseParams(params int[] list)

{

for (int i = 0 ; i < list.Length; i++)

{

Page 52: CSharp Handout v1.0

Handout - C#

Page 52 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Console.WriteLine(list[i]);

}

Console.WriteLine();

}

public static void UseParams2(params object[] list)

{

for (int i = 0 ; i < list.Length; i++)

{

Console.WriteLine(list[i]);

}

Console.WriteLine();

}

static void Main()

{

UseParams(1, 2, 3);

UseParams2(1, 'a', "test");

// An array of objects can also be passed, as long as

// the array type matches the method being called.

int[] myarray = new int[3] {10,11,12};

UseParams(myarray);

}

}

ref: The ref keyword causes arguments to be passed by reference. The effect is that any changes made to the parameter in the method will be reflected in that variable when control passes back to the calling method. To use a ref parameter, both the method definition and the calling method must explicitly use the ref keyword. For example: class RefExample

{

static void Method(ref int i)

{

i = 44;

}

static void Main()

{

int val = 0;

Method(ref val);

// val is now 44

}

}

Page 53: CSharp Handout v1.0

Handout - C#

Page 53 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Out: The out keyword causes arguments to be passed by reference. This is similar to the ref keyword, except that ref requires that the variable be initialized before being passed. To use an out parameter, both the method definition and the calling method must explicitly use the out keyword. Example: class OutExample

{

static void Method(out int i)

{

i = 44;

}

static void Main()

{

int value;

Method(out value);

// value is now 44

}

}

Method Overloading

Overloading is the creation of more than one procedure, instance constructor, or property in a class with the same name but different argument types. Rules for Overloading: You create an overloaded member for a class by adding two or more properties or methods with the same name. Except for overloaded derived members, each overloaded member must have different parameter lists, and the following items cannot be used as a differentiating feature when overloading a property or procedure:

Modifiers, such as ByVal or ByRef, that applies to a member or parameters of the member.

Names of parameters Return types of procedures

The following is an example for overloading: using System;

namespace overload

{

class Program

{

void add(int a, int b)

{

int result;

result=a+b;

Page 54: CSharp Handout v1.0

Handout - C#

Page 54 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Console.WriteLine("The sum of two integers is :" + result);

}

void add(string a, string b)

{

string result;

result = a + b;

Console.WriteLine("The concatenation of two strings is :" + result);

}

static void Main(string[] args)

{

Program obj = new Program();

obj.add(1, 2);

obj.add("Hi ", "Yaso");

}

}

}

Summary

Arrays: Single-dimensional array: It is the simplest form of arrays Multidimensional array: It is an array with more than one dimension. Jagged Array: They are often called array of arrays. An element of a jagged array

itself is an array. Mixed arrays: It is a combination of multi-dimension arrays and jagged arrays.

Methods: A method is a code block containing a series of statements. Methods are declared by specifying the access level, the return value, the name of the

method, and any method parameters. Parameters: Parameters are means of passing values to a method. Different types of parameters are as follows: Method Overloading: Method overloading is a way to have more than one method

having the same name, but each method has a different signature.

Test your Understanding

1. What are the types of arrays? 2. What is jagged array and how do you declare it? 3. What is method and how do you define it? 4. What are the types of parameters? 5. State the difference between parameter and parameter value. 6. What do you mean by Method Overloading?

Page 55: CSharp Handout v1.0

Handout - C#

Page 55 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 11: Creating Value with Enumerations and Structs

Learning Objectives

After completing this session, you will be able to: Explain Enumeration in C# Explain Struct in C#

Enumerations

An enum type declaration defines a type name for a related group of symbolic constants. An enum is a special form of value type, which inherits from System.Enum and supplies alternate names for the values of an underlying primitive type. The underlying type must be one of the built-in signed or unsigned integer types (such as Byte, Int32, or UInt64). You can assign a value of the underlying type to an enumeration and vice versa (no cast is required by the runtime). Enums are used for multiple choice scenarios, in which a runtime decision is made from a fixed number of choices that are known at compile-time. enum Color

{

Red,

Blue,

Green

}

The use of enums is superior to the use of integer constants because the use of enums makes the code more readable and self-documenting. The self-documenting nature of the code also makes it possible for the development tool to assist with code writing. For example, the use of Color rather than int for a parameter type enables smart code editors like VS.NET to suggest Color values. Also it mandates certain check constraints like in the following sample, the signature of the Fill method makes it clear that the shape can be filled with one of the given colors. public void Fill(Color myColor) {

myColor2 = myColor;

myColor3 = 0;

//...

if( myColor == Color.Red)

/...

}

Page 56: CSharp Handout v1.0

Handout - C#

Page 56 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

The following are the members of the E-num class. Public Methods:

S.No Name Description

1 CompareTo Compares this instance to a specified object and returns an indication of their relative values.

2 Equals Overloaded. Overridden. Returns a value indicating whether this instance is equal to a specified object.

3 Format Converts the specified value of a specified enumerated type to its equivalent string representation according to the specified format.

4 GetHashcode Overridden. Returns the hash code for the value of this instance.

5 GetName Retrieves the name of the constant in the specified enumeration that has the specified value.

6 GetNames Retrieves an array of the names of the constants in a specified enumeration.

7 GetType Gets the Type of the current instance. (Inherited from Object.)

8 GetTypeCode Returns the underlying TypeCode for this instance.

9 GetUnderlyingType Returns the underlying type of the specified enumeration.

10 GetValues Retrieves an array of the values of the constants in a specified enumeration.

11 IsDefined Returns an indication whether a constant with a specified value exists in a specified enumeration.

12 Parse Overloaded. Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.

13 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

14 ToObject Overloaded. Returns an instance of the specified enumeration type set to the specified value.

15 ToString Overloaded. Overridden. Converts the value of this instance to its equivalent string representation.

Protected Methods:

S.No. Name Description

1 Finalize Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

2 MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)

Page 57: CSharp Handout v1.0

Handout - C#

Page 57 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

In this example, an enumeration, Days is declared. Two enumerators are explicitly converted to integer and assigned to integer variables. // keyword_enum.cs

// enum initialization:

using System;

public class EnumTest

{

enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};

static void Main()

{

int x = (int)Days.Sun;

int y = (int)Days.Fri;

Console.WriteLine("Sun = {0}", x);

Console.WriteLine("Fri = {0}", y);

}

}

Structs

A struct type is a value type that is typically used to encapsulate small groups of related variables, such as the coordinates of a rectangle or the characteristics of an item in an inventory. The following example shows a simple struct declaration: Public struct Book

{

Public decimal price;

Public string title;

Public string author;

}

Structs share almost all the same syntax as classes, although structs are more limited than classes:

Struct instance field declarations cannot use initializers, although static fields on structs can be initialized.

A struct not declare a default constructor —a constructor with no parameters — or a destructor.

Copies of structs are created and destroyed automatically by the compiler, so a default constructor and destructor are unnecessary. In effect, the compiler implements the default constructor by assigning all the fields of their default values .Structs cannot inherit from classes or other structs. Structs are value types — when an object is created from a struct and assigned to a variable, the variable contains the entire value of the struct. When a variable containing a struct is copied, all of the data is copied, and any modification to the new copy does not change the data for the old copy. Because structs do not use references, they do not have identity — there is no way to distinguish between two instances of a value type with the same data. All value types in C# inherently derive from ValueType, which inherits from Object.

Page 58: CSharp Handout v1.0

Handout - C#

Page 58 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Structs have the following properties: Structs are value types while classes are reference types. When passing a struct to a method, it is passed by value instead of as a reference. Unlike classes, structs can be instantiated without using a new operator. Structs can declare constructors, but they must take parameters. A struct cannot inherit from another struct or class, and it cannot be the base of a

class. All structs inherit directly from System.ValueType, which inherits from System.Object.

A struct can implement interfaces. It is an error to initialize an instance field in a struct.

Structs can also contain constructors, constants, fields, methods, properties, indexers, operators, events, and nested types, although if several such members are required, you should consider making your type a class instead. Structs can implement an interface but they cannot inherit from another struct. For that reason, struct members cannot be declared as protected.

Summary

Enumerations: It is a data type consisting of a set of named values that represent integral constants.

Struct: It contains an ordered group of data objects and is defined using struct keyword.

Test your Understanding

1. Why do you go for Enumeration? 2. State the difference between structs and classes? 3. What is called as a set of named constants? 4. Are structs suitable only for a small data type?

Page 59: CSharp Handout v1.0

Handout - C#

Page 59 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 12: Classes and Objects

Learning Objectives

After completing this session, you will be able to: Explain basics of OOPS Explain Classes and Objects Define Abstraction, Encapsulation, Inheritance, and Polymorphism

Fundamentals of object-oriented programming

The fundamental principle of object-oriented programming is that a program is composed of a collection of individual units, or objects that can function like sub-programs. To make the overall computation happen, each object is capable of receiving messages, processing data, and sending messages to other objects. In short, the objects can interact through their own functions (or methods) and their own data. The key to understanding object-oriented design is understanding what classes are and what you can do with them. Classes are templates that you use to create actual objects. The instructions contained in a class are used to create one or more objects, which can be called instances of classes. When you create an object from a class, you instantiate the object, which means you create an instance of the class. In object-oriented programming, you can think of an object as you would any real-world object, for example, a rectangle. The actual rectangle would be an instance of the class Rectangle. A very rudimentary declaration of a class is as follows: Class Rectangle {

//class instructions

}

The instructions in a class are made of two basic components: variables that hold data, and methods that manipulate the data. Variables: Classes store information that describes objects in instance variables. When objects are created from a class, they contain new instances of the class' variables. These instance variables can have values that are different from one object to the next. Values of instance variables are called data. When an instance variable's data is changed, it affects only the individual object. Two variables that might be declared for a rectangle are length and width.

Page 60: CSharp Handout v1.0

Handout - C#

Page 60 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Methods: Methods are functions that must be associated with individual classes. In C and C++ and other procedural languages, functions can be placed anywhere in the code. In C#, they must be stored within classes. Instances of methods are created when instances of classes are created. Unlike variables, methods are not duplicated in objects-their code is stored only in the class. When an object's method is invoked from its class, it uses the data of variables in the object. Every method returns a value if it is not declared as void. To declare a method, you use the following statement: returntype methodname (parameter list)

{ //method code }

Characteristics of an object-oriented language

Object-oriented programming emphasizes the following concepts: Objects: Packaging data and functionality together into units within a running program; objects are the basis of modularity and structure in an object-oriented program. Abstraction: The ability for a program to ignore some aspects of the information that it is manipulating, i.e. the ability to focus on the essential. Each object in the system serves as a model of an abstract "actor" that can perform work, report on and change its state, and "communicate" with other objects in the system, without revealing how these features are implemented. Processes, functions or methods may also be so abstracted, and when they are, a variety of techniques are required to extend an abstraction: Encapsulation: Also called information hiding: Ensures that users of an object cannot change the internal state of the object in unexpected ways; only the object's own internal methods are allowed to access its state. Each class exposes an interface that specifies how other classes may interact with it. This prevents users from breaking the invariants of the class, which is useful because it allows the implementation of a class of objects to be changed for aspects not exposed in the interface without impact to user code. The definitions of encapsulation focus on the grouping and packaging of related information (cohesion) rather than security issues. OOP languages do not normally offer formal security restrictions to the internal object state. Using a method of access is a matter of convention for the interface design. Polymorphism: Different things or objects can have the same interface or answer the same message (based on message name) and respond appropriately depending on the thing's nature or type. This potentially allows multiple things to be interchangeable with each other. For example, if a bird receives the message "move fast", it will flap its wings and fly. If a lion receives the same message, it will run with its legs. Both answer the same request, but in ways appropriate to each creature.

Page 61: CSharp Handout v1.0

Handout - C#

Page 61 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Inheritance: Organizes and facilitates polymorphism and encapsulation by permitting objects to be defined and created that are specialized types of already-existing objects - these can share (and extend) their behavior without having to reimplement that behavior. This is typically done by grouping objects into classes, and defining classes as extensions of existing classes, thus and grouping classes into trees or lattices reflecting behavioral commonality.

Inheritance, Overriding and Overloading

If you want an object that is very similar to one we already have, but with a few extra characteristics. You just inherit a new class based on the class of the similar object. Inheritance is the process of creating a new class with the characteristics of an existing class, along with additional characteristics unique to the new class. Inheritance provides a powerful and natural mechanism for organizing and structuring programs. Members and methods that are stored in classes in the class hierarchy are inherited by subclasses, so you do not need to re-create them. Objects created from a subclass will contain not only the instances of the variables and methods of the child class, but also its parent class' members and methods, as well as those of the parent of its parent class, and so on. When a members or method is referenced in an object, it is retrieved in a specific order: compiler first searches for it in the current class, then, if it is not found, it searches the parent class, and so on. Class inheritance is designed to allow as much flexibility as possible. You can create inheritance trees as deep as necessary to carry out your design. An inheritance tree, or class hierarchy, looks much like a family tree; it shows the relationships between classes. Unlike a family tree, the classes in an inheritance tree get more specific as you move down the tree. You create a derived class by adding a colon after the name of the derived class, followed by the name of the base class: public class Honda : Car

Page 62: CSharp Handout v1.0

Handout - C#

Page 62 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Calling Base Class Constructors The Honda class constructor invokes the constructor of its parent by placing a colon (:) after the parameter list and then invoking the base class with the keyword base. If the base class has an accessible default constructor, the derived constructor is not required to invoke the base constructor, as the default constructor is called implicitly. 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. public void Honda() : base

{

this.Model = "Honda";

}

Calling Base Class Methods If a class needs to call a method in the base class then this is achieved using the base keyword followed by the method required in the usual manner using dot notation. base.StartCar();

Unlike C++, multiple inheritances are not allowed in C# and a similar effect can be achieved using interfaces, which is discussed shortly. In some cases, a class may want to 'overwrite' a base method. C# supports two different ways of method overwriting - 'hiding' or 'overriding'. Note that the term 'overwrite' is a term we have devised to cover both hiding and overriding. Method overwriting makes use of the following three method-head keywords: new, virtual, override. The main difference between hiding and overriding relates to the choice of which method to call where the declared class of a variable is different to the run-time class of the object it references. This point is explained further below.

Method Overriding

Suppose that you define a Square class which inherits from a Rectangle class (a square being a special case of a rectangle). Each of these classes also specifies a 'getArea' instance method, returning the area of the given instance. For the Square class to 'override' the Rectangle class' getArea method, the Rectangle class' method must have first declared that it is happy to be overridden. One way in which it can do this is with the 'virtual' keyword. So, for instance, the Rectangle class' getArea method might be specified like this: public virtual double getArea()

{

return length * width;

}

Page 63: CSharp Handout v1.0

Handout - C#

Page 63 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

To override this method the Square class would then specify the overriding method with the 'override' keyword. For example: public virtual double getArea()

{

return length * length;

}

Note that for one method to override another, the overridden method must not be static, and it must be declared as either 'virtual', 'abstract' or 'override'. Furthermore, the access modifiers for each method must be the same. The major implication of the specifications above is that if we construct a new Square instance and then call its 'getArea' method, the method actually called will be the Square instance's getArea method. So, for instance, if you run the following code: Square sq = new Square(5);

double area = sq.getArea();

Then the getArea method called on the second line will be the method defined in the Square class. There is, however, a more subtle point. To show this, suppose that you declare two variables in the following way: Square sq = new Square(4);

Rectangle r = sq;

Here variable r refers to sq as a Rectangle instance (possible because the Square class derives from the Rectangle class). You can now raise the question: if you run the following code double area = r.getArea();

Then which getArea method is actually called - the Square class method or the Rectangle class method? The answer in this case is that the Square class method would still be called. Because the Square class' getArea method 'overrides' the corresponding method in the Rectangle class, calls to this method on a Square instance always 'slide through' to the overriding method. Method Hiding Where one method 'hides' another, the hidden method does not need to be declared with any special keyword. Instead, the hiding method just declares itself as 'new'. So, where the Square class hides the Rectangle class' getArea method, the two methods might just be written thus: public double getArea() // in Rectangle

{

return length * width;

}

public new double getArea() // in Square

{

return length * length;

}

Note that a method can 'hide' another one without the access modifiers of these methods being the same. So, for instance, the Square's getArea method could be declared as private,

Page 64: CSharp Handout v1.0

Handout - C#

Page 64 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Overloaded Methods You use overloaded methods in your code when you need to call a method with different sets of parameter lists. Methods that allow flexibility in the parameters they use can be called from different parts of your program with different variables. To allow a different type of parameter information to be passed to your method, repeat the method in your code with the alternate parameter list included, as follows: returnvalue methodname (parameter list 1) returnvalue methodname (parameter list 2)

It is possible to extend when the method is called and parameters are passed to it, compiler determines which version of the method has a parameter list that most closely matches the parameters passed and executes it.

Polymorphism

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. Polymorphism is important not only to the derived classes, but to the base classes as well. Anyone using the base class could, in fact, be using an object of the derived class that has been cast to the base class type. Polymorphism means that you can have multiple classes that can be used interchangeably, even though each class implements the same properties or methods in different ways. Polymorphism is essential to object-oriented programming because it allows you to use items with the same names, no matter what type of object is in use at the moment. 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, you have two choices: you can replace the base member with a new derived member, or you can override a virtual base member. Replacing a member of a base class with a new derived member requires the new keyword. The new keyword is placed before the return type of a class member that is being replaced. Example:

public class BaseClass

{

public void DoWork() { }

public int WorkField;

public int WorkProperty

{

get { return 0; }

}

}

Page 65: CSharp Handout v1.0

Handout - C#

Page 65 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

public class DerivedClass : BaseClass

{

public new void DoWork() { }

public new int WorkField;

public new int WorkProperty

{

get { return 0; }

}

}

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. For example: DerivedClass B = new DerivedClass();

B.DoWork(); // Calls the new method.

BaseClass A = (BaseClass)B;

A.DoWork(); // Calls the old method.

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. Example: public class BaseClass

{

public virtual void DoWork() { }

public virtual int WorkProperty

{

get { return 0; }

}

}

public class DerivedClass : BaseClass

{

public override void DoWork() { }

public override int WorkProperty

{

get { return 0; }

}

}

Page 66: CSharp Handout v1.0

Handout - C#

Page 66 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

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. Example: DerivedClass B = new DerivedClass();

B.DoWork(); // Calls the new method.

BaseClass A = (BaseClass)B;

A.DoWork(); // Also calls the new method.

Summary

Abstraction is used to manage complexity. Encapsulation promotes “information hiding”. Inheritance aids in the reuse of code. Polymorphism means ability to take more than one form.

Test your Understanding

1. Why do you need to go for OOPS? 2. Differenciate between Object Oriented and Procedural Oriented programming. 3. What are classes and objects? 4. What is Inheritance? 5. What is Polymorphism?

Page 67: CSharp Handout v1.0

Handout - C#

Page 67 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 13: Classes and Objects

Learning Objectives

After completing the session, you will be able to: Define Classes and Objects Explain Properties and Indexers Describe Access Modifiers

Classes and Objects

You discussed the myriad primitive types built into the C# language, such as int, long, and char. The heart and soul of C#, however, is the ability to create new, complex, programmer-defined types that map cleanly to the objects that make up the problem you are trying to solve. It is this ability to create new types that characterizes an object-oriented language. You specify new types in C# by declaring and defining classes. Also we saw how we can define types with interfaces. Instances of a class are called objects. Objects are created in memory when your program executes. The difference between a class and an object is the same as the difference between the concept of a car and a particular car like Toyota Camry. You can't drive with the definition of a car, but only with an instance, Toyota Camry. A car class describes what cars are like: they have weight, height, color, wheels and so forth. They also have actions they can take, such as drive, brake, and horn. A particular car will have a specific weight, height, color and so forth. The following table shows Public Methods of System. Object Objects:

Method Means

Equals Indicates whether two Object instances are equal.

GetHashCode Serves as a hash function for a particular type.

GetType Returns the Type of the current instance.

Reference Equals

Determines whether the specified Object instances are the same instance.

ToString Returns a String that represents the current Object.

The huge advantage of classes in object-oriented programming is that they encapsulate the characteristics and capabilities of an entity in a single, self-contained and self-sustaining unit of code. When you want to sort the contents of an instance of a Windows list box control, for example, you tell the list box to sort itself. How it does so is of no concern; that it does so is all you need to know. Encapsulation, along with polymorphism and inheritance, is one of three cardinal principles of object-oriented programming.

Page 68: CSharp Handout v1.0

Handout - C#

Page 68 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

When you define a new class, you define the characteristics of all objects of that class, as well as their behaviors. For example, if you create a listbox, a control that is very useful for presenting a list of choices to the user and enabling the user to select from the list. Listboxes have a variety of characteristics: height, width, location, and text color, for example. Programmers have also come to expect certain behaviors of listboxes — they can be opened, closed, sorted, and so on. To define a new type or class, you first declare it and then define its methods and fields. You declare a class using the class keyword. The complete syntax is as follows: [attributes] [modifiers] class identifier [:base-list] { class-body }[;]

Attributes (Optional): Attributes hold additional declarative information. Modifiers (Optional): The allowed modifiers are new, static, virtual, abstract, override,

and a valid combination of the four access modifiers Identifier: The class name. Base-list (Optional): A list that contains the base class and any implemented

interfaces, separated by commas. Class-body: Declarations of the class members.

The following example demonstrates the usage of class and object. using System;

namespace Sum

{

class Sum

{

void add(int a, int b)

{

int result;

result=a+b;

Console.WriteLine("The sum of two integers is :" + result);

}

static void Main(string[] args)

{

Sum objSum= new Sum();

objSum.add(1, 2);

}

}

}

Properties

Properties allow clients to access class state as if they were accessing member fields directly, while actually implementing that access through a class method. This is ideal. The client wants direct access to the state of the object and does not want to work with methods. The class designer, however, wants to hide the internal state of his class in class members, and provide indirect access through a method.

Page 69: CSharp Handout v1.0

Handout - C#

Page 69 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

By decoupling the class state from the method that accesses that state, the designer is free to change the internal state of the object as needed. When the Time class is first created, the Hour value might be stored as a member variable. When the class is redesigned, the Hour value might be computed, or retrieved from a database. If the client had direct access to the original Hour member variable, the change to computing the value would break the client. By decoupling and forcing the client to go through a method (or property), the Time class can change how it manages its internal state without breaking client code. Properties meet both goals: they provide a simple interface to the client, appearing to be a member variable. They are implemented as methods, however, providing the data hiding required by good object-oriented design, The following code snippet shows how to create and use a property. The Time class has the Hours property implementation. Notice that the first letter of the first word is capitalized. That's the only difference between the names of the property Hours and the field iHours. The property has two accessors, get and set. The get accessor returns the value of the iHours field. The set accessor sets the value of the iHours field with the contents of value. The value shown in the set accessor is a C# reserved word. public class Time

{

private int iHours = 0;

public int Hours

{ get

{

return iHours;

}

set

{

iHours = value;

}

}

}

Whenever you reference the property (other than to assign to it), the get accessor is invoked to read the value of the property: Time oTime = new Time();

int iCurrentHour = oTime.Hour;

Properties can be made read-only or write-only. This is accomplished by having only a get or set accessor in the property implementation.

Indexers

There are times when it is desirable to access a collection within a class as though the class itself were an array. For example, suppose you create a list box control named myListBox that contains a list of strings stored in a one-dimensional array, a private member variable named myStrings. A list box control contains member properties and methods in addition to its array of strings.

Page 70: CSharp Handout v1.0

Handout - C#

Page 70 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

However, it would be convenient to be able to access the list box array with an index, just as if the list box were an array. For example, such a property would permit statements like the following: string theFirstString = myListBox[0];

string theLastString = myListBox[Length-1];

An indexer is a C# construct that allows you to access collections contained by a class using the familiar [] syntax of arrays. An indexer is a special kind of property and includes get( ) and set() methods to specify its behavior. You declare an indexer property within a class using the following syntax: type this [type argument]{get; set;}

The return type determines the type of object that will be returned by the indexer, while the type argument specifies what kind of argument will be used to index into the collection that contains the target objects. Although it is common to use integers as index values, you can index a collection on other types as well, including strings. You can even provide an indexer with multiple parameters to create a multidimensional array! This keyword is a reference to the object in which the indexer appears. As with a normal property, you also must define get( ) and set( ) methods that determine how the requested object is retrieved from or assigned to its collection. public class SimpleIndexer

{

private string[] myData;

public IntIndexer(int size)

{

myData = new string[size];

for (int i=0; i < size; i++)

{

myData[i] = "empty";

}

}

public string this[int pos]

{ get

{

return myData[pos];

}

set

{

myData[pos] = value;

}

}

}

//usage of the indexer

SimpleIndexer oSimpleIndexer = new SimpleIndexer(10)

oSimpleIndexer[0] = "Cognizant Academy";

Page 71: CSharp Handout v1.0

Handout - C#

Page 71 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Using an integer is a common means of accessing arrays in many languages, but the C# Indexer goes beyond this. Indexers can be declared with multiple parameters and each parameter may be a different type. Additional parameters are separated by commas, the same as a method parameter list. Valid parameter types for Indexers include integers, enums, and strings. Additionally, Indexers can also be overloaded. class OvrIndexer

{

private string[] myData;

private int arrSize;

public OvrIndexer(int size)

{

arrSize = size;

myData = new string[size];

for (int i=0; i < size; i++)

{

myData[i] = "empty";

}

}

public string this[int pos]

{ get

{

return myData[pos];

}

set

{

myData[pos] = value;

}

}

public string this[string data]

{ get

{

int count = 0;

for (int i=0; i < arrSize; i++)

{

if (myData[i] == data)

{

count++;

}

}

return count.ToString();

}

set

{

for (int i=0; i < arrSize; i++)

{

Page 72: CSharp Handout v1.0

Handout - C#

Page 72 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

if (myData[i] == data)

{

myData[i] = value;

}

}

}

}

//usage of an overloaded indexer

OvrIndexer myInd = new OvrIndexer(10);

myInd[9] = "Some Value";

myInd[3] = "Another Value";

myInd[5] = "Any Value";

myInd["empty"] = "no value";

The reason both Indexers in above code can coexist in the same class is because they have different signatures. An Indexer signature is specified by the number and type of parameters in an Indexers parameter list. The class will be smart enough to figure out which Indexer to invoke, based on the number and type of arguments in the Indexer call. An indexer with multiple parameters would be implemented something like this: public object this[int param1, ..., int paramN]

{

get

{

// process and return some class data

}

set

{

// process and assign some class data

}

}

Access Modifiers

Access modifiers are keywords used to specify the declared accessibility of a member or a type. This section introduces the four access modifiers:

public protected internal private

Page 73: CSharp Handout v1.0

Handout - C#

Page 73 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

The following five accessibility levels can be specified using the access modifiers: public: Access is not restricted. protected: Access is limited to the containing class or types derived from the

containing class. Internal: Access is limited to the current assembly. protected internal: Access is limited to the current assembly or types derived from

the containing class. private: Access is limited to the containing type.

This section also introduces the following:

Accessibility Levels: Using the four access modifiers to declare five levels of accessibility.

Accessibility Domain: Specifies where, in the program sections, a member can be referenced.

Restrictions on Using Accessibility Levels: A summary of the restrictions on using declared accessibility levels.

Accessibility levels Use the access modifiers, public, protected, internal, or private to specify one of the following declared accessibilities for members.

Declared accessibility Meaning public Access is not restricted.

protected Access is limited to the containing class or types derived from the containing class.

internal Access is limited to the current assembly.

protected internal Access is limited to the current assembly or types derived from the containing class.

private Access is limited to the containing type.

Only one access modifier is allowed for a member or type, except when using the protected internal combination. Access modifiers are not allowed on namespaces. Namespaces have no access restrictions. Depending on the context in which a member declaration takes place, only certain declared accessibilities are permitted. If no access modifier is specified in a member declaration, a default accessibility is used. Top-level types, which are not nested into other types, can only have internal or public accessibility. The default accessibility for these types is internal. Nested types, which are members of other types, can have declared accessibilities as indicated in the following table.

Members Default member accessibility Allowed declared accessibility of the member enum public None

Page 74: CSharp Handout v1.0

Handout - C#

Page 74 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Members Default member accessibility Allowed declared accessibility of the member class private public

protected

internal

private

protected internal

interface public None

struct private public

internal

private

The accessibility of a nested type depends on its accessibility domain, which is determined by both the declared accessibility of the member and the accessibility domain of the immediately containing type. However, the accessibility domain of a nested type cannot exceed that of the containing type. Accessibility Domain The accessibility domain of a member specifies where, in the program sections, a member can be referenced. If the member is nested within another type, then its accessibility domain is determined by both the accessibility level of the member and the accessibility domain of the immediately containing type. The accessibility domain of a top-level type is at least the program text of the project in which it is declared. That is, the entire source files of this project. The accessibility domain of a nested type is at least the program text of the type in which it is declared. That is, the type body, including any nested types. The accessibility domain of a nested type never exceeds that of the containing type. These concepts are demonstrated in the following example. Example: This example contains a top-level type, T1, and two nested classes, M1 and M2. The classes contain fields with different declared accessibilities. In the Main method, a comment follows each statement to indicate the accessibility domain of each member. Notice that the statements that attempt to reference the inaccessible members are commented out. If you want to see the compiler errors caused by referencing an inaccessible member, remove the comments one at a time. // cs_Accessibility_Domain.cs

using System;

namespace AccessibilityDomainNamespace

{

public class T1

{

public static int publicInt;

internal static int internalInt;

private static int privateInt = 0; // CS0414

Page 75: CSharp Handout v1.0

Handout - C#

Page 75 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

public class M1

{

public static int publicInt;

internal static int internalInt;

private static int privateInt = 0; // CS0414

}

private class M2

{

public static int publicInt = 0;

internal static int internalInt = 0;

private static int privateInt = 0; // CS0414

}

}

class MainClass

{

static void Main()

{

// Access is unlimited:

T1.publicInt = 1;

// Accessible only in current assembly:

T1.internalInt = 2;

// Error: inaccessible outside T1:

// T1.myPrivateInt = 3;

// Access is unlimited:

T1.M1.publicInt = 1;

// Accessible only in current assembly:

T1.M1.internalInt = 2;

// Error: inaccessible outside M1:

// T1.M1.myPrivateInt = 3;

// Error: inaccessible outside T1:

// T1.M2.myPublicInt = 1;

// Error: inaccessible outside T1:

// T1.M2.myInternalInt = 2;

// Error: inaccessible outside M2:

// T1.M2.myPrivateInt = 3;

}

}

}

Page 76: CSharp Handout v1.0

Handout - C#

Page 76 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Restrictions on using Accessibility levels When you declare a type, it is essential to see if that type has to be at least as accessible as another member or type. For example, the direct base class must be at least as accessible as the derived class. The following declarations will result in a compiler error, because the base class BaseClass is less accessible than MyClass: class BaseClass {...}

public class MyClass: BaseClass {...} // Error

The following table summarizes the restrictions on using declared accessibility levels:

Context Remarks

Classes The direct base class of a class type must be at least as accessible as the class type itself.

Interfaces The explicit base interfaces of an interface type must be at least as accessible as the interface type itself.

Delegates The return type and parameter types of a delegate type must be at least as accessible as the delegate type itself.

Constants The type of a constant must be at least as accessible as the constant itself.

Fields The type of a field must be at least as accessible as the field itself.

Methods The return type and parameter types of a method must be at least as accessible as the method itself.

Properties The type of a property must be at least as accessible as the property itself.

Events The type of an event must be at least as accessible as the event itself.

Indexers The type and parameter types of an indexer must be at least as accessible as the indexer itself.

Operators The return type and parameter types of an operator must be at least as accessible as the operator itself.

Constructors The parameter types of a constructor must be at least as accessible as the constructor itself.

The following example contains erroneous declarations of different types. The comment following each declaration indicates the expected compiler error: // Restrictions_on_Using_Accessibility_Levels.cs

// CS0052 expected as well as CS0053, CS0056, and CS0057

// To make the program work, change access level of both class B

// and MyPrivateMethod() to public.

using System;

Page 77: CSharp Handout v1.0

Handout - C#

Page 77 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

// A delegate:

delegate int MyDelegate();

class B

{

// A private method:

static int MyPrivateMethod()

{

return 0;

}

}

public class A

{

// Error: The type B is less accessible than the field A.myField.

public B myField = new B();

// Error: The type B is less accessible

// than the constant A.myConst.

public readonly B myConst = new B();

public B MyMethod()

{

// Error: The type B is less accessible

// than the method A.MyMethod.

return new B();

}

// Error: The type B is less accessible than the property A.MyProp

public B MyProp

{

set

{

}

}

MyDelegate d = new MyDelegate(B.MyPrivateMethod);

// Even when B is declared public, you still get the error:

// "The parameter B.MyPrivateMethod is not accessible due to protection level."

public static B operator +(A m1, B m2)

{

// Error: The type B is less accessible

// than the operator A.operator +(A,B)

return new B();

}

static void Main()

{

Console.Write("Compiled successfully");

Page 78: CSharp Handout v1.0

Handout - C#

Page 78 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

}

}

Summary

Following are the five types of access levels: o Public o Protected o Internal o Protected internal o Private

Properties combine aspects of both fields and methods. Indexers are also called smart arrays in C#. Indexers treat an object as an array.

Test your Understanding

1. State the differences between protected internal and internal access levels. 2. Explain the usage of Internal Keyword. 3. What are the accessors in properties? 4. What are indexers?

Page 79: CSharp Handout v1.0

Handout - C#

Page 79 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 14: Classes and Objects

Learning Objectives

After completing this session, you will be able to: Define Static Methods, Variables, and Classes Explain Nested classes and Partial classes

Static Methods, Variables and Classes

When a method declaration includes a static modifier, that method is said to be a static method. When no static modifier is present, the method is said to be an instance method.A static method does not operate on a specific instance, and it is a compile-time error to refer to this in a static method. using System;

namespace ReverseString

{

class ReverseStringDemo

{

static void Main(string[] args)

{

string s = "Yasodhai";

string r = Helpers.Reverse(s);

Console.WriteLine(r);

}

}

static class Helpers

{

public static string Reverse(string s)

{

char[] c = s.ToCharArray();

Array.Reverse(c);

return new string(c);

}

}

}

A field declared with the static modifier is called a static variable. A static variable comes into existence before execution of the static constructor (Section 10.11) for its containing type, and

Page 80: CSharp Handout v1.0

Handout - C#

Page 80 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

ceases to exist when the associated application domain ceases to exist. Static Variables will be alive throughout the life of a program. The following example demonstrates the usage of a static variable. using System;

namespace Test

{

class Test

{

static int x = 0;

static int y = 5;

static void Main()

{

Console.WriteLine(Test.x);

Console.WriteLine(Test.y);

Test.x = 99;

Console.WriteLine(Test.x);

Console.ReadLine();

}

}

}

Partial Classes

It is possible to split the definition of a class or a struct, or an interface over two or more source files. Each source file contains a section of the class definition, and all parts are combined when the application is compiled. There are several situations when splitting a class definition is desirable: When working on large projects, spreading a class over separate files allows multiple programmers to work on it simultaneously.When working with automatically generated source, code can be added to the class without having to recreate the source file. Visual Studio uses this approach when creating Windows Forms, Web Service wrapper code, and so on. You can create code that uses these classes without having to edit the file created by Visual Studio. To split a class definition, use the partial keyword modifier which is shown as follows: public partial class Employee

{

public void DoWork()

{

}

}

public partial class Employee

{

public void GoToLunch()

Page 81: CSharp Handout v1.0

Handout - C#

Page 81 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

{

}

}

Using the partial keyword indicates that other parts of the class, struct, or interface can be defined within the namespace. All the parts must use the partial keyword. All of the parts must be available at compile time to form the final type. All the parts must have the same accessibility, such as public, private, and so on. If any of the parts are declared abstract, then the entire type is considered abstract. If any of the parts are declared sealed, then the entire type is considered sealed. If any of the parts declare a base type, then the entire type inherits that class. All of the parts that specify a base class must agree, but parts that omit a base class still inherit the base type. Parts can specify different base interfaces, and the final type implements all of the interfaces listed by all of the partial declarations. Any class, struct, or interface members declared in a partial definition are available to all of the other parts. The final type is the combination of all the parts at compile time. Nested types can be partial, even if the type they are nested within is not partial itself. For example: class Container

{

partial class Nested

{

void Test() { }

}

partial class Nested

{

void Test2() { }

}

}

At compile time, attributes of partial-type definitions are merged. For example, the following declarations: [System.SerializableAttribute]

partial class Moon { }

[System.ObsoleteAttribute]

partial class Moon { }

This is equivalent to: [System.SerializableAttribute]

[System.ObsoleteAttribute]

class Moon { }

Page 82: CSharp Handout v1.0

Handout - C#

Page 82 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Nested Classes

A class can be declared within the scope of another class. Such a class is called a "nested class." Nested classes are considered to be within the scope of the enclosing class and are available for use within that scope. To refer to a nested class from a scope other than its immediate enclosing scope, you must use a fully qualified name. The following example shows how to declare nested classes: // nested_class_declarations.cpp

class BufferedIO

{

public:

enum IOError { None, Access, General };

// Declare nested class BufferedInput.

class BufferedInput

{

public:

int read();

int good()

{

return _inputerror == None;

}

private:

IOError _inputerror;

};

// Declare nested class BufferedOutput.

class BufferedOutput

{

// Member list

};

};

int main()

{

}

BufferedIO::BufferedInput and BufferedIO::BufferedOutput are declared within BufferedIO. These class names are not visible outside the scope of class BufferedIO. However, an object of type BufferedIO does not contain any objects of types BufferedInput or BufferedOutput. Nested classes can directly use names, type names, names of static members, and enumerators only from the enclosing class. To use names of other class members, you must use pointers, references, or object names.

Page 83: CSharp Handout v1.0

Handout - C#

Page 83 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

In the preceding BufferedIO example, the enumeration IOError can be accessed directly by member functions in the nested classes, BufferedIO::BufferedInput or BufferedIO::BufferedOutput, as shown in function good.

Summary

Those methods and variables which do not need an instance of a class to be created are defined as being static.

A class defined inside another one is called a nested class. Partial classes means that your class definition going to be split into multiple physical

files.

Test your Understanding

1. What is the concept of partial class in .net 2.0? 2. Why do you go for Partial classes? 3. Define the scope of the static variables. 4. Define the concept of Nested classes.

Page 84: CSharp Handout v1.0

Handout - C#

Page 84 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 17: Inheritance and Interface

Learning Objectives

After completing this session, you will be able to:: Explain Inheritance Define Abstract Classes and Interfaces Describe Polymorphism using Interfaces

Inheritance

If you want an object that is very similar to one we already have, but with a few extra characteristics. You just inherit a new class based on the class of the similar object. Inheritance is the process of creating a new class with the characteristics of an existing class, along with additional characteristics unique to the new class. Inheritance provides a powerful and natural mechanism for organizing and structuring programs. Members and methods that are stored in classes in the class hierarchy are inherited by subclasses, so you do not need to re-create them. Objects created from a subclass will contain not only the instances of the variables and methods of the child class, but also its parent class' members and methods, as well as those of the parent of its parent class, and so on. When a members or method is referenced in an object, it is retrieved in a specific order: compiler first searches for it in the current class, then, if it is not found, it searches the parent class, and so on. Class inheritance is designed to allow as much flexibility as possible. You can create inheritance trees as deep as necessary to carry out your design. An inheritance tree, or class hierarchy, looks much like a family tree; it shows the relationships between classes. Unlike a family tree, the classes in an inheritance tree get more specific as you move down the tree. You create a derived class by adding a colon after the name of the derived class, followed by the name of the base class: public class Honda : Car

Calling Base Class Constructors: The Honda class constructor invokes the constructor of its parent by placing a colon (:) after the parameter list and then invoking the base class with the keyword base. If the base class has an accessible default constructor, the derived constructor is not required to invoke the base constructor, as the default constructor is called implicitly. 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. public void Honda() : base

{

this.Model = "Honda";

}

Page 85: CSharp Handout v1.0

Handout - C#

Page 85 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Calling Base Class Methods: If a class needs to call a method in the base class then this is achieved using the base keyword followed by the method required in the usual manner using dot notation. base.StartCar ();

Unlike C++, multiple inheritances are not allowed in C# and a similar effect can be achieved using interfaces, which is discussed shortly. In some cases, a class may want to 'overwrite' a base method. C# supports two different ways of method overwriting - 'hiding' or 'overriding'. Note that the term 'overwrite' is a term we have devised to cover both hiding and overriding. Method overwriting makes use of the following three method-head keywords: new, virtual, override. The main difference between hiding and overriding relates to the choice of which method to call where the declared class of a variable is different to the run-time class of the object it references. This point is explained further below.

Abstract Class

The abstract keyword enables to create classes and class members solely for the purpose of inheritance—to define features of derived, non-abstract classes. Classes can be declared as abstract. This is accomplished by putting the keyword abstract before the keyword class in the class definition. Example: Public abstract class A

{

// Class members here.

}

An abstract class cannot be instantiated. The purpose of an abstract class is to provide a common definition of a base class that multiple derived classes can share. For example, a class library may define an abstract class that is used as a parameter to many of its functions, and require programmers using that library to provide their own implementation of the class by creating a derived class. Abstract classes may also define abstract methods. This is accomplished by adding the keyword abstract before the return type of the method. For example: Public abstract class A

{

Public abstract void DoWork (int i);

}

Page 86: CSharp Handout v1.0

Handout - C#

Page 86 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Abstract methods have no implementation, so the method definition is followed by a semicolon instead of a normal method block. Derived classes of the abstract class must implement all abstract methods. When an abstract class inherits a virtual method from a base class, the abstract class can override the virtual method with an abstract method. Example: public class D

{

Public virtual void DoWork (int i);

{

// Original implementation.

}

}

Public abstract class E : D

{

Public abstract override void DoWork (int i);

}

Public class F; E

{

Public override void DoWork(int i);

{

// New implementation

}

}

If a virtual method is declared abstract, it is still virtual to any class inheriting from the abstract class. A class inheriting an abstract method cannot access the original implementation of the method—in the previous example; DoWork on class F cannot call DoWork on class D. In this way, an abstract class can force derived classes to provide new method implementations for virtual methods.

Interface

There are situations when we don't want to create a new type. Rather, to describe a set of behaviors that any number of types might implement. For example, we want to describe what it means to be storable (that is, capable of being written to disk) or printable. Such a description is called an interface. An interface is a contract; the designer of the interface says "if you want to provide this capability, you must implement these methods." The implementer of the interface agrees to the contract and implements the required methods. When a class implements an interface, it tells any potential client "it will support the methods, properties, events, and indexers of the named interface." The interface details the return type from each method and the parameters to the methods.

Page 87: CSharp Handout v1.0

Handout - C#

Page 87 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

The syntax for defining an interface is very similar to the syntax for defining a class or a struct: [access-modifier ] interface interface-name [: base-list ] {interface-body }

Access modifiers (public, private, and so on.) work just as they do with classes. (Refer Session 13 for more about access modifiers.) The interface keyword is followed by an identifier (the interface name). It is common (but not required) to begin the name of your interface with a capital I (IStorable, an existing interface to add new methods or members, or to modify how existing members work. pubic interface IStorable

{

void Read();

void Write(object);

}

If you are designing a to new class say Document class, that will support this feature, then you implement this interface like this. public class Document : IStorable

It is the responsibility of the Document class, to provide a meaningful implementation of the IStorable methods. Having designated Document as implementing IStorable, it must implement all the IStorable methods, or it will generate an error when you compile. An interface can define that the implementing class will provide a property (Refer Session 13 for a discussion of properties). Notice that the IStorable method declarations for Read() and Write() do not include access modifiers (For example, public, protected, internal, private). In fact, providing an access modifier generates a compile error. Interface methods are implicitly public because an interface is a contract meant to be used by other classes. As mentioned earlier, Classes can derive from only one class, but classes can implement any number of interfaces. public class Document : IStorable, ICompressible

Casting to an Interface: You cannot instantiate an interface directly; that is, you cannot write: IStorable isDoc = new IStorable();

Instead you instantiate a class that implements the interface. Casting is safe to do because the Document object implements IStorable and thus is safely treated as an IStorable object. You cast by placing the type you are casting to in parentheses. The following line declares a variable of type IStorable and assigns to that variable the Document object, cast to type IStorable: Document doc = new Document("Test Document");

IStorable isDoc = (IStorable) doc;

isDoc.Read();

Page 88: CSharp Handout v1.0

Handout - C#

Page 88 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

There may be instances in which you do not know in advance (at compile time) that an object supports a particular interface. For instance, given a collection of objects, you might not know whether each object in the collection implements IStorable, ICompressible, or both. The is operator lets you query whether an object implements an interface. if (doc is IStorable)

{

IStorable isDoc = (IStorable) doc;

isDoc.Read();

}

Summary

Inheritance: Inheritance is the process of creating a new class with the characteristics of an existing class, along with additional characteristics unique to the new class.

Abstract Class: The abstract keyword enables to create classes and class members solely for the purpose of inheritance—to define features of derived, non-abstract classes. Classes can be declared as abstract.

Interfaces: Interfaces, like classes, define a set of properties, methods, and events. But unlike classes, interfaces do not provide implementation. They are implemented by classes, and defined as separate entities from classes.

Test Your Understanding

1. What is inheritance? 2. Does C# support multiple inheritances? 3. What is the advantage of using inheritance? 4. What is an abstract class? 5. How do you achieve multiple inheritances in C#? 6. Differenciate between abstract class and interfaces.

Page 89: CSharp Handout v1.0

Handout - C#

Page 89 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 21: Nunit

Learning Objectives

After completing this session, you will be able to: Perform Unit testing using N-Unit

Nunit:

In order to test an application under NUnit, you write test code that is specially annotated using custom Attributes. Your test code contains Assertions, which demonstrate the correct working of the application. If your application stores settings in Configuration Files, NUnit provides you with the ability to have settings for your test, which are different from those used in production. In addition to running tests in a single assembly, NUnit provides support for tests organized as Multiple Assemblies and for creating and running tests as NUnit Test Projects.

Assertions

Assertions are central to unit testing in any of the xUnit frameworks, and NUnit is no exception. NUnit provides a rich set of assertions as static methods of the Assert class. If an assertion fails, the method call does not return and an error is reported. If a test contains multiple assertions any that follow the one that failed will not be executed. For this reason, it's usually best to try for one assertion per test. Each method may be called without a message, with a simple text message or with a message and arguments. In the last case the message is formatted using the provided text and arguments.

Classic Assert Model

The classic Assert model uses a separate method to express each individual assertion of which it is capable. Here is a simple assert using the classic model: StringAssert.AreEqualIgnoringCase( "Hello", myString );

The Assert class provides the most commonly used assertions. Assert methods are grouped as follows:

Equality Asserts Identity Asserts Comparison Asserts Type Asserts Condition tests

Page 90: CSharp Handout v1.0

Handout - C#

Page 90 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Utility methods Beyond the basic facilities of Assert, additional assertions are provided by the following classes:

StringAssert CollectionAssert FileAssert

Equality Asserts

These methods test whether the two arguments are equal. Overloaded methods are provided for common value types so that languages that do not automatically box values can use them directly. Assert.AreEqual( int expected, int actual );

Assert.AreEqual( int expected, int actual, string message );

Assert.AreEqual( int expected, int actual, string message, params object[] parms );

Assert.AreEqual( uint expected, uint actual );

Assert.AreEqual( uint expected, uint actual, string message );

Assert.AreEqual( uint expected, uint actual, string message, params object[] parms );

Assert.AreEqual( decimal expected, decimal actual );

Assert.AreEqual( decimal expected, decimal actual, string message );

Assert.AreEqual(decimal expected, decimal act, string message, params object[] parms );

Assert.AreEqual( float expected, float actual, float tolerance );

Assert.AreEqual( float expected, float actual, float tolerance, string message );

Assert.AreEqual( float exptd, float act, float tolera, string msg, params object[] parms );

Assert.AreEqual( double expected, double actual, double tolerance );

Assert.AreEqual( double expected, double actual, double tolerance, string message );

Assert.AreEqual( double exptd, double act, double tolerance, string msg, params object[] parms );

Assert.AreEqual( object expected, object actual );

Assert.AreEqual( object expected, object actual, string message );

Assert.AreEqual( object expected, object actual, string message, params object[] parms );

Assert.AreNotEqual( int expected, int actual );

Assert.AreNotEqual( int expected, int actual, string message );

Page 91: CSharp Handout v1.0

Handout - C#

Page 91 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Assert.AreNotEqual( int expected, int actual, string message, params object[] parms );

Assert.AreNotEqual( long expected, long actual );

Assert.AreNotEqual( long expected, long actual, string message );

Assert.AreNotEqual( long expected, long actual, string message, params object[] parms );

Assert.AreNotEqual( uint expected, uint actual );

Assert.AreNotEqual( uint expected, uint actual, string message );

Assert.AreNotEqual( uint expected, uint actual, string message, params object[] parms );

Assert.AreNotEqual( ulong expected, ulong actual );

Assert.AreNotEqual( ulong expected, ulong actual, string message );

Assert.AreNotEqual( ulong expected, ulong act, string message, params object[] parms );

Assert.AreNotEqual( decimal expected, decimal actual );

Assert.AreNotEqual( decimal expected, decimal actual, string message );

Assert.AreNotEqual( decimal expected, decimal act, string msg, params object[] parms );

Assert.AreNotEqual( float expected, float actual );

Assert.AreNotEqual( float expected, float actual, string message );

Assert.AreNotEqual( float expected, float actual, string message, params object[] parms );

Assert.AreNotEqual( double expected, double actual );

Assert.AreNotEqual( double expected, double actual, string message );

Assert.AreNotEqual( double expected, double act, string msg, params object[] parms );

Assert.AreNotEqual( object expected, object actual );

Assert.AreNotEqual( object expected, object actual, string message );

Assert.AreNotEqual( object expected, object act, string msg, params object[] parms );

Page 92: CSharp Handout v1.0

Handout - C#

Page 92 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Condition Tests

Methods that test a specific condition are named for the condition they test and take the value tested as their first argument and, optionally a message as the second. The following methods are provided: Assert.IsTrue( bool condition );

Assert.IsTrue( bool condition, string message );

Assert.IsTrue( bool condition, string message, object[] parms );

Assert.IsFalse( bool condition);

Assert.IsFalse( bool condition, string message );

Assert.IsFalse( bool condition, string message, object[] parms );

Assert.IsNull( object anObject );

Assert.IsNull( object anObject, string message );

Assert.IsNull( object anObject, string message, object[] parms );

Assert.IsNotNull( object anObject );

Assert.IsNotNull( object anObject, string message );

Assert.IsNotNull( object anObject, string message, object[] parms );

Assert.IsNaN( double aDouble );

Assert.IsNaN( double aDouble, string message );

Assert.IsNaN( double aDouble, string message, object[] parms );

Assert.IsEmpty( string aString );

Assert.IsEmpty( string aString, string message );

Assert.IsEmpty( string aString, string message, params object[] args );

Assert.IsNotEmpty( string aString );

Assert.IsNotEmpty( string aString, string message );

Assert.IsNotEmpty( string aString, string message, params object[] args );

Assert.IsEmpty( ICollection collection );

Assert.IsEmpty( ICollection collection, string message );

Assert.IsEmpty( ICollection collection, string message, params object[] args );

Assert.IsNotEmpty( ICollection collection );

Assert.IsNotEmpty( ICollection collection, string message );

Assert.IsNotEmpty( ICollection collection, string message, params object[] args );

Assert.AreNotEqual( object expected, object act, string msg, params object[] parms );

Page 93: CSharp Handout v1.0

Handout - C#

Page 93 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Comparisons

The following methods test whether one object is greater than than another. Contrary to the normal order of Asserts, these methods are designed to be read in the "natural" English-language or mathematical order. Thus Assert.Greater( x, y ) asserts that x is greater than y ( x > y ). Assert.Greater( int arg1, int arg2 );

Assert.Greater( int arg1, int arg2, string message );

Assert.Greater( int arg1, int arg2, string message, object[] parms );

Assert.Greater( uint arg1, uint arg2 );

Assert.Greater( uint arg1, uint arg2, string message );

Assert.Greater( uint arg1, uint arg2, string message, object[] parms );

Assert.Greater( long arg1, long arg2 );

Assert.Greater( long arg1, long arg2, string message );

Assert.Greater( long arg1, long arg2, string message, object[] parms );

Assert.Greater( ulong arg1, ulong arg2 );

Assert.Greater( ulong arg1, ulong arg2, string message );

Assert.Greater( ulong arg1, ulong arg2, string message, object[] parms );

Assert.Greater( decimal arg1, decimal arg2 );

Assert.Greater( decimal arg1, decimal arg2, string message );

Assert.Greater( decimal arg1, decimal arg2, string message, object[] parms );

Assert.Greater( double arg1, double arg2 );

Assert.Greater( double arg1, double arg2, string message );

Assert.Greater( double arg1, double arg2, string message, object[] parms );

Assert.Greater( double arg1, double arg2 );

Assert.Greater( double arg1, double arg2, string message );

Assert.Greater( double arg1, double arg2, string message, object[] parms );

Assert.Greater( float arg1, float arg2 );

Assert.Greater( float arg1, float arg2, string message );

Assert.Greater( float arg1, float arg2, string message, object[] parms );

Assert.Greater( IComparable arg1, IComparable arg2 );

Assert.Greater( IComparable arg1, IComparable arg2, string message );

Page 94: CSharp Handout v1.0

Handout - C#

Page 94 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Assert.Greater( IComparable arg1, IComparable arg2, string message, object[] parms );

The following methods test whether one object is greater than or equal to another. Contrary to the normal order of Asserts, these methods are designed to be read in the "natural" English-language or mathematical order. Thus Assert.GreaterOrEqual( x, y ) asserts that x is greater than or equal to y ( x >= y ). Assert.GreaterOrEqual( int arg1, int arg2 );

Assert.GreaterOrEqual( int arg1, int arg2, string message );

Assert.GreaterOrEqual( int arg1, int arg2, string message, object[] parms );

Assert.GreaterOrEqual( uint arg1, uint arg2 );

Assert.GreaterOrEqual( uint arg1, uint arg2, string message );

Assert.GreaterOrEqual( uint arg1, uint arg2, string message, object[] parms );

Assert.GreaterOrEqual( long arg1, long arg2 );

Assert.GreaterOrEqual( long arg1, long arg2, string message );

Assert.GreaterOrEqual( long arg1, long arg2, string message, object[] parms );

Assert.GreaterOrEqual( ulong arg1, ulong arg2 );

Assert.GreaterOrEqual( ulong arg1, ulong arg2, string message );

Assert.GreaterOrEqual( ulong arg1, ulong arg2, string message, object[] parms );

Assert.GreaterOrEqual( decimal arg1, decimal arg2 );

Assert.GreaterOrEqual( decimal arg1, decimal arg2, string message );

Assert.GreaterOrEqual( decimal arg1, decimal arg2, string message, object[] parms );

Assert.GreaterOrEqual( double arg1, double arg2 );

Assert.GreaterOrEqual( double arg1, double arg2, string message );

Assert.GreaterOrEqual( double arg1, double arg2, string message, object[] parms );

Assert.GreaterOrEqual( double arg1, double arg2 );

Assert.GreaterOrEqual( double arg1, double arg2, string message );

Assert.GreaterOrEqual( double arg1, double arg2, string message, object[] parms );

Assert.GreaterOrEqual( float arg1, float arg2 );

Assert.GreaterOrEqual( float arg1, float arg2, string message );

Assert.GreaterOrEqual( float arg1, float arg2, string message, object[] parms );

Page 95: CSharp Handout v1.0

Handout - C#

Page 95 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Assert.GreaterOrEqual( IComparable arg1, IComparable arg2 );

Assert.GreaterOrEqual( IComparable arg1, IComparable arg2, string message );

Assert.GreaterOrEqual( IComparable arg1, IComparable arg2, string message, object[] parms );

The following methods test whether one object is less than than another. Contrary to the normal order of Asserts, these methods are designed to be read in the "natural" English-language or mathematical order. Thus Assert.Less( x, y ) asserts that x is less than y ( x < y ). Assert.Less( int arg1, int arg2 );

Assert.Less( int arg1, int arg2, string message );

Assert.Less( int arg1, int arg2, string message, object[] parms );

Assert.Less( uint arg1, uint arg2 );

Assert.Less( uint arg1, uint arg2, string message );

Assert.Less( uint arg1, uint arg2, string message, object[] parms );

Assert.Less( long arg1, long arg2 );

Assert.Less( long arg1, long arg2, string message );

Assert.Less( long arg1, long arg2, string message, object[] parms );

Assert.Less( ulong arg1, ulong arg2 );

Assert.Less( ulong arg1, ulong arg2, string message );

Assert.Less( ulong arg1, ulong arg2, string message, object[] parms );

Assert.Less( decimal arg1, decimal arg2 );

Assert.Less( decimal arg1, decimal arg2, string message );

Assert.Less( decimal arg1, decimal arg2, string message, object[] parms );

Assert.Less( double arg1, double arg2 );

Assert.Less( double arg1, double arg2, string message );

Assert.Less( double arg1, double arg2, string message, object[] parms );

Assert.Less( float arg1, float arg2 );

Assert.Less( float arg1, float arg2, string message );

Assert.Less( float arg1, float arg2, string message, object[] parms );

Assert.Less( IComparable arg1, IComparable arg2 );

Assert.Less( IComparable arg1, IComparable arg2, string message );

Assert.Less( IComparable arg1, IComparable arg2, string message, object[] parms );

Page 96: CSharp Handout v1.0

Handout - C#

Page 96 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

The following methods test whether one object is less than or equal to another. Contrary to the normal order of Asserts, these methods are designed to be read in the "natural" English-language or mathematical order. Thus Assert.LessOrEqual( x, y ) asserts that x is less than or equal to y ( x <= y ). Assert.LessOrEqual( int arg1, int arg2 );

Assert.LessOrEqual( int arg1, int arg2, string message );

Assert.LessOrEqual( int arg1, int arg2, string message, object[] parms );

Assert.LessOrEqual( uint arg1, uint arg2 );

Assert.LessOrEqual( uint arg1, uint arg2, string message );

Assert.LessOrEqual( uint arg1, uint arg2, string message, object[] parms );

Assert.LessOrEqual( long arg1, long arg2 );

Assert.LessOrEqual( long arg1, long arg2, string message );

Assert.LessOrEqual( long arg1, long arg2, string message, object[] parms );

Assert.LessOrEqual( ulong arg1, ulong arg2 );

Assert.LessOrEqual( ulong arg1, ulong arg2, string message );

Assert.LessOrEqual( ulong arg1, ulong arg2, string message, object[] parms );

Assert.LessOrEqual( decimal arg1, decimal arg2 );

Assert.LessOrEqual( decimal arg1, decimal arg2, string message );

Assert.LessOrEqual( decimal arg1, decimal arg2, string message, object[] parms );

Assert.LessOrEqual( double arg1, double arg2 );

Assert.LessOrEqual( double arg1, double arg2, string message );

Assert.LessOrEqual( double arg1, double arg2, string message, object[] parms );

Assert.LessOrEqual( float arg1, float arg2 );

Assert.LessOrEqual( float arg1, float arg2, string message );

Assert.LessOrEqual( float arg1, float arg2, string message, object[] parms );

Assert.LessOrEqual( IComparable arg1, IComparable arg2 );

Assert.LessOrEqual( IComparable arg1, IComparable arg2, string message );

Assert.LessOrEqual( IComparable arg1, IComparable arg2, string message, object[] parms );

Page 97: CSharp Handout v1.0

Handout - C#

Page 97 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Attributes

Version 1 of NUnit used the classic approach to identifying tests based on inheritance and naming conventions. From version 2.0 on, NUnit has used custom attributes for this purpose. Because NUnit test fixtures do not inherit from a framework class, the developer is free to use inheritance in other ways. And because there is no arbitrary convention for naming tests, the choice of names can be entirely oriented toward communicating the purpose of the test. All NUnit attributes are contained in the NUnit.Framework namespace. Each source file that contains tests must include a using statement for that namespace and the project must reference the framework assembly, nunit.framework.dll.

TestFixtureAttribute

This is the attribute that marks a class that contains tests and, optionally, setup or teardown methods. There are a few restrictions on a class that is used as a test fixture.

It must be a publicly exported type. It must have not been abstract. It must have a default constructor It must have no more than one of each of the following method types: SetUp,

TearDown, TestFixtureSetUp and TestFixtureTearDown. If any of these restrictions are violated, then the class will be shown as a non-runnable test fixture, and will turn yellow in the GUI if you attempt to run it. using System;

using NUnit.Framework;

namespace NUnit.Tests

{

[TestFixture]

public class SuccessTests

{

// ...

}

}

TestFixtureSetUpAttribute

This attribute is used inside a TestFixture to provide a single set of functions that are performed once prior to executing any of the tests in the fixture. A TestFixture can have only one TestFixtureSetUp method. If more than one is defined the TestFixture will compile successfully but its tests will not run. using System;

using NUnit.Framework;

namespace NUnit.Tests

{

[TestFixture]

public class SuccessTests

{

[TestFixtureSetUp] public void Init()

Page 98: CSharp Handout v1.0

Handout - C#

Page 98 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

{ /* ... */ }

[TestFixtureTearDown] public void Dispose()

{ /* ... */ }

[Test] public void Add()

{ /* ... */ }

}

}

TestFixtureTearDownAttribute

This attribute is used inside a TestFixture to provide a single set of functions that are performed once after all tests are completed. A TestFixture can have only one TestFixtureTearDown method. If more than one is defined the TestFixture will compile successfully but its tests will not run. So long as any TestFixtureSetUp method runs without error, the TestFixtureTearDown method is guaranteed to run. It will not run if a TestFixtureSetUp method fails or throws an exception.

TestAttribute

The Test attribute marks a specific method inside a class that has already been marked as a TestFixture, as a test method. For backwards compatibility with previous versions of Nunit a test method will also be found if the first 4 letters are "test" regardless of case. The signature for a test method is defined as follows: public void MethodName()

Note that there must be no parameters. If the programmer marks a test method that does not have the correct signature, then it will not be run and it will appear in the Test Not Run area in the UI that ran the program. using System;

using NUnit.Framework;

namespace NUnit.Tests

{

using System;

using NUnit.Framework;

[TestFixture]

public class SuccessTests

{

[Test] public void Add()

{ /* ... */ }

public void TestSubtract()

{ /* backwards compatibility */ }

}

}

Page 99: CSharp Handout v1.0

Handout - C#

Page 99 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Configuration Files

NUnit uses configuration files for the test runner executable – either nunit-console.exe or nunitgui.exe – as well as for the tests being run. Only settings that pertain to NUnit itself should be in the nunit-console.exe.config and nunit-gui.exe.config, while those that pertain to your own application and tests should be in a separate configuration file.

NUnit Configuration Files

One main purpose of the nunit-console and nunit-gui config files is to allow NUnit to run with various versions of the .NET framework. NUnit is built using versions 1.1 and 2.0 of the framework. The two builds are provided as separate downloads and either build can be made to run against other versions of the CLR. As delivered, the section of each config file is commented out, causing NUnit to run with the version of .NET used to build it. If you uncomment the section, the entries there control the order in which alternate framework versions are selected.

Test Configuration File

When a configuration file is used to provide settings or to control the environment in which a test is run, specific naming conventions must be followed. If a single assembly is being loaded, then the configuration file is given the name of the assembly file with the config extension. For example, the configuration file used to run nunit.tests.dll must be named nunit.tests.dll.config and located in the same directory as the dll. f an NUnit project is being loaded into a single AppDomain, the configuration file uses the name of the project file with the extension changed to config. For example, the project AllTests.nunit would require a configuration file named AllTests.config, located in the same directory as AllTests.nunit. The same rule is followed when loading Visual Studio projects or solutions. Generally, you should be able to simply copy your application config file and rename it as described above. However, see the next section if you wish to run tests compiled for an earlier version of NUnit.

Multiple-Assembly Support

As version 2.1, NUnit has allowed loading suites of tests from multiple assemblies in both the console and GUI runners. This may be done on an adhoc basis or by creating NUnit test projects saved as files of type '.nunit'. In either case, a top-level suite is constructed, which contains the root suite for each assembly. Tests are run and reported just as for a single assembly.

Adhoc Usage

Using the console runner, multiple assemblies may be run simply by specifying their names on the command line. The GUI runner does not support specifying multiple assemblies on the command-line. However, you can load a single assembly and then use the Project menu to add additional assemblies. Additionally, you can drag multiple assemblies to the tree view pane, in which case they will replace any assemblies already loaded.

Page 100: CSharp Handout v1.0

Handout - C#

Page 100 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

NUnit Test Projects

Running tests from multiple assemblies is facilitated by the use of NUnit test projects. These are files with the extension .nunit containing information about the assemblies to be loaded. The following is an example of a hypothetical test project file: <NUnitProject>

<Settings activeconfig="Debug"/>

<Config name="Debug">

<assembly path="LibraryCore\bin\Debug\Library.dll"/>

<assembly path="LibraryUI\bin\Debug\LibraryUI.dll"/>

</Config>

<Config name="Release">

<assembly path="LibraryCore\bin\Release\Library.dll"/>

<assembly path="LibraryUI\bin\Release\LibraryUI.dll"/>

</Config>

</NUnitProject>

This project contains two configurations, each of which contains two assemblies. The Debug configuration is currently active. By default, the assemblies will be loaded using the directory containing this file as the ApplicationBase. The PrivateBinPath will be set automatically to LibraryCore\bin\Debug;LibraryUI\bin\Debug or to the corresonding release path. XML attributes are used to specify non-default values for the ApplicationBase, Configuration File and PrivateBinPath. The Project Editor may be used to create or modify NUnit projects. Even when you are running a single test assembly, NUnit creates an internal project to contain that assembly. If you are using the gui, you can save this project, edit it, add additional assemblies, etc. Note that the gui does not display the internal project unless you add assemblies or modify it in some other way. If you use Visual Studio Support to load Visual Studio .Net project or solution files, NUnit converts them to Test projects internally. As with other internal projects, these test projects are not saved automatically but may be saved by use of the File menu.

Loading and Running

In the past, test writers have been able to rely on the current directory being set to the directory containing the single loaded assembly. For the purpose of compatibility, NUnit continues to set the current directory to the directory containing each assembly whenever any test from that assembly is run. Additionally, because some assemblies may rely on unmanaged dlls in the same directory, the current directory is also set to that of the assembly at the time the assembly is loaded. However, in cases where multiple assemblies reference the same unmanaged assembly, this may not be sufficient and the user may need to place the directory containing the unmanaged dll on the path.

Visual Studio Support

Visual Studio support in this release is a sort of “poor man’s integration.” We have implemented a number of features while avoiding any that would require using an Addin or otherwise interacting with the Visual Studio extensibility model.

Page 101: CSharp Handout v1.0

Handout - C#

Page 101 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Running From Within Visual Studio

The most convenient way to do this is to set up a custom tool entry specifying the path to NUnit-gui.exe as the command. For a C# project, you may wish to use $(TargetPath) for the arguments and $(TargetDir) for the initial directory. If you would like to debug your tests, use the Visual Studio Debug | Processes… menu item to attach to nunit-gui.exe after starting it and set breakpoints in your test code as desired before running the tests.

Using Console Interface to Debug Applications

When the nunit-console program is run in debug mode under Visual Studio, it detects that it is running in this mode and sends output to the Visual Studio output window. Output is formatted so that double clicking any error or failure entries opens the appropriate test file at the location where the failure was detected.

Opening Visual Studio Projects

When Visual Studio support is enabled, the File Open dialog displays the following supported Visual Studio project types: C#, VB.Net, J# and C++. The project file is read and the configurations and output assembly locations are identified. Since the project files do not contain information about the most recently opened configuration, the output assembly for the first configuration found (usually Debug) is loaded in the GUI. The tree shows the project as the toplevel node with the assembly shown as its descendant. When tests are run for a Visual studio project, they run just as if the output assembly had been loaded with one exception. The default location for the config file is the directory containing the project file and it’s default name is the same as the project file with an extension of .config. For example, the following command would load the tests in the nunit.tests assembly using the configuration file nunit.tests.dll.config located in the same directory as the dll. nunit-gui.exe nunit.tests.dll

On the other hand, the following command would load the tests using the configuration file nunit.tests.config located in the same directory as the csproj file. nunit-gui.exe nunit.tests.csproj

The same consideration applies to running tests using the console runner.

Opening Visual Studio Solutions

When Visual Studio support is enabled, solution files may be opened as well. All the output assemblies from contained projects of the types supported will be loaded in the tree. In the case where all contained projects are located in the subdirectories beneath the solution, it will be possible to load and run tests using this method directly. When a solution contains projects located elsewhere in the file system, it may not be possible to run the tests – although the solution will generally load without problem. In this case, the Project Editor should be use to modify and save the NUnit test project so that there is all referenced assemblies are located in or beneath the application base directory.

Page 102: CSharp Handout v1.0

Handout - C#

Page 102 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Adding Visual Studio Projects to the Open Test Project

When Visual Studio support is enabled, the Project menu contains an active entry to add a VS project to the loaded project. The output assembly will be added for each of the configurations specified in the VS project.

Summary

NUnit provides a powerful framework for Unit Testing. Synopsis on Unit testing and how it can be utilized for appropriate exception handling,

best practices, coding guidelines, and so on.

Test your Understanding

1. What are the different types of Assert? 2. What is the syntax of Equality Assert? 3. What is the use of TearDown method? 4. How many TearDown methods can be declared in a program?

Page 103: CSharp Handout v1.0

Handout - C#

Page 103 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 23: Generics and Collections

Learning Objectives

After completing this session, you will be able to: Define Generic Types Describe the Generic Methods Explain Constraints in Generics

Generics

Generics are classes, structures, interfaces, and methods that have placeholders (type parameters) for one or more of the types they store or use. A generic collection class might use a type parameter as a placeholder for the type of objects it stores; the type parameters appear as the types of its fields, and the parameter types of its methods. A generic method might use its type parameter as the type of its return value, or as the type of one of its formal parameters. The following code illustrates a simple generic class definition. Generics are most commonly used with collections and the methods that operate on them. public class Generic<T>

{

public T Field;

}

Example: // Declare the generic class

public class GenericList<T>

{

void Add(T input) { }

}

class TestGenericList

{

private class ExampleClass { }

static void Main()

{

// Declare a list of type int

GenericList<int> list1 = new GenericList<int>();

// Declare a list of type string

GenericList<string> list2 = new GenericList<string>();

// Declare a list of type ExampleClass

GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();

}

}

Page 104: CSharp Handout v1.0

Handout - C#

Page 104 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Advantages of Generics: By allowing you to specify the specific types acted on by a generic class or method,

the generics feature shifts the burden of type safety from you to the compiler. There is no need to write code to test for the correct data type, because it is enforced

at compile time. The need for type casting and the possibility of run-time errors are reduced.

Generics provide type safety without the overhead of multiple implementations. Constraints on Type Parameters:

When define a generic class, you can apply restrictions to the kinds of types that client code can use for type arguments when it instantiates your class. If client code attempts to instantiate your class with a type that is not allowed by a constraint, the result is a compile-time error. These restrictions are called constraints. Constraints are specified using the where contextual keyword. The following table lists the five types of constraints:

Constraint Description where T: struct The type argument must be a value type. Any value type except Nullable

can be specified. See Using Nullable Types (C# Programming Guide) for more information.

where T : class The type argument must be a reference type, including any class, interface, delegate, or array type.

where T : new() The type argument must have a public parameterless constructor. When used in conjunction with other constraints, the new() constraint must be specified last.

where T : <base class name>

The type argument must be or derive from the specified base class.

where T : <interface name>

The type argument must be or implement the specified interface. Multiple interface constraints can be specified. The constraining interface can also be generic.

where T : U The type argument supplied for T must be or derive from the argument supplied for U. This is called a naked type constraint.

Why do you use Constraints?

If you want to examine an item in a generic list to determine whether it is valid or to compare it to some other item, the compiler must have some guarantee that the operator or method it needs to call will be supported by any type argument that might be specified by client code. This guarantee is obtained by applying one or more constraints to our generic class definition

Page 105: CSharp Handout v1.0

Handout - C#

Page 105 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Generic Methods: A generic method is a method that is declared with type parameters, as follows:

static void Swap<T>(ref T lhs, ref T rhs)

{

T temp;

temp = lhs;

lhs = rhs;

rhs = temp;

}

The following code example shows one way to call the method, using int for the type argument: Public static void Testswap()

{

Int a=1;

Int b=2;

Swap<int>(ref a, ref b);

System.Console.writeline (a+””+b);

}

Classes in Generics

The System.Collections.Generic namespace contains interfaces and classes that define generic collections, which allow users to create strongly typed collections that provide better type safety and performance than non-generic strongly typed collections.Some of the classes in this namespace, are as follows:

S.No Class Description

1 Dictionary Represents a collection of keys and values.

2 List Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists.

3 Queue Represents a first-in, first-out collection of objects.

4 Stack Represents a variable size last-in-first-out (LIFO) collection of instances of the same arbitrary type.

Dictionary Class:

Represents a collection of keys and values. Namespace:System.Collections.Generic

Assembly: mscorlib (in mscorlib.dll) Syntax:

[SerializableAttribute]

[ComVisibleAttribute(false)]

public class Dictionary<TKey,TValue> : IDictionary<TKey,TValue>,

Page 106: CSharp Handout v1.0

Handout - C#

Page 106 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

ICollection<KeyValuePair<TKey,TValue>>,IEnumerable<KeyValuePair<TKey,TValue>>, IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback

Members: Public Properties:

S.No Name Description

1 Comparer Gets the IEqualityComparer that is used to determine equality of keys for the dictionary.

2 Count Gets the number of key/value pairs contained in the Dictionary.

3 Item Gets or sets the value associated with the specified key.

4 Keys Gets a collection containing the keys in the Dictionary.

5 Values Gets a collection containing the values in the Dictionary.

Public Methods:

S.No Name Description

1 Add Adds the specified key and value to the dictionary.

2 Clear Removes all keys and values from the Dictionary.

3 ContainsKey Determines whether the Dictionary contains the specified key.

4 ContainsValue Determines whether the Dictionary contains a specific value.

5 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

6 GetEnumerator Returns an enumerator that iterates through the Dictionary.

7 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

8 GetObjectData Implements the System.Runtime.Serialization.ISerializable interface and returns the data needed to serialize the Dictionary instance.

9 GetType Gets the Type of the current instance. (Inherited from Object.)

10 OnDeserialization Implements the System.Runtime.Serialization.ISerializable interface and raises the deserialization event when the deserialization is complete.

11 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

12 Remove Removes the value with the specified key from the Dictionary.

13 ToString Returns a String that represents the current Object. (Inherited from Object.)

14 TryGetValue Gets the value associated with the specified key.

Page 107: CSharp Handout v1.0

Handout - C#

Page 107 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Protected Methods:

S.No Name Description

1 Finalize Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

2 MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)

List Class:

Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists.

Namespace:System.Collections.Generic Assembly: mscorlib (in mscorlib.dll)

Syntax:

[SerializableAttribute]

public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable

Members: Public properties:

S.No Name Description 1 Capacity Gets or sets the total number of elements the internal data structure can

hold without resizing.

2 Count Gets the number of elements actually contained in the List.

3 Item Gets or sets the element at the specified index.

Public Methods:

S.No Name Description

1 Add Adds an object to the end of the List.

2 AddRange Adds the elements of the specified collection to the end of the List.

3 AsReadOnly Returns a read-only IList wrapper for the current collection.

4 BinarySearch Overloaded. Uses a binary search algorithm to locate a specific element in the sorted List or a portion of it.

5 Clear Removes all elements from the List.

6 Contains Determines whether an element is in the List.

7 ConvertAll Converts the elements in the current List to another type, and returns a list containing the converted elements.

8 CopyTo Overloaded. Copies the List or a portion of it to an array.

9 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

Page 108: CSharp Handout v1.0

Handout - C#

Page 108 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

10 Exists Determines whether the List contains elements that match the conditions defined by the specified predicate.

11 Find Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire List.

12 FindAll Retrieves the all the elements that match the conditions defined by the specified predicate.

13 FindIndex Overloaded. Searches for an element that matches the conditions defined by a specified predicate, and returns the zero-based index of the first occurrence within the List or a portion of it.

14 FindLast Searches for an element that matches the conditions defined by the specified predicate, and returns the last occurrence within the entire List.

15 FindLastIndex Overloaded. Searches for an element that matches the conditions defined by a specified predicate, and returns the zero-based index of the last occurrence within the List or a portion of it.

16 ForEach Performs the specified action on each element of the List.

17 GetEnumerator Returns an enumerator that iterates through the List.

18 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

19 GetRange Creates a shallow copy of a range of elements in the source List.

20 GetType Gets the Type of the current instance. (Inherited from Object.)

21 IndexOf Overloaded. Returns the zero-based index of the first occurrence of a value in the List or in a portion of it.

22 Insert Inserts an element into the List at the specified index.

23 InsertRange Inserts the elements of a collection into the List at the specified index.

24 LastIndexOf Overloaded. Returns the zero-based index of the last occurrence of a value in the List or in a portion of it.

25 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

26 Remove Removes the first occurrence of a specific object from the List.

27 RemoveAll Removes the all the elements that match the conditions defined by the specified predicate.

28 RemoveAt Removes the element at the specified index of the List.

29 RemoveRange Removes a range of elements from the List.

30 Reverse Overloaded. Reverses the order of the elements in the List or a portion of it.

31 Sort Overloaded. Sorts the elements in the List or a portion of it.

Page 109: CSharp Handout v1.0

Handout - C#

Page 109 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

32 ToArray Copies the elements of the List to a new array.

33 ToString Returns a String that represents the current Object. (Inherited from Object.)

34 TrimExcess Sets the capacity to the actual number of elements in the List, if that number is less than a threshold value.

35 TrueForAll Determines whether every element in the List matches the conditions defined by the specified predicate.

Protected Methods:

S.No Name Description

1 Finalize Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

2 MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)

Queue Class:

Represents a first-in, first-out collection of objects. Namespace:System.Collections.Generic

Assembly: System (in system.dll) Syntax:

[SerializableAttribute]

[ComVisibleAttribute(false)]

public class Queue<T> : IEnumerable<T>, ICollection, IEnumerable

Members: Public Properties:

S.No Name Description

1 Count Gets the number of elements contained in the Queue.

Public Methods:

S.No Name Description

1 Clear Removes all objects from the Queue.

2 Contains Determines whether an element is in the Queue.

3 CopyTo Copies the Queue elements to an existing one-dimensional Array, starting at the specified array index.

4 Dequeue Removes and returns the object at the beginning of the Queue.

5 Enqueue Adds an object to the end of the Queue.

6 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

Page 110: CSharp Handout v1.0

Handout - C#

Page 110 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

7 GetEnumerator Returns an enumerator that iterates through the Queue.

8 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

9 GetType Gets the Type of the current instance. (Inherited from Object.)

10 Peek Returns the object at the beginning of the Queue without removing it.

11 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

12 ToArray Copies the Queue elements to a new array.

13 ToString Returns a String that represents the current Object. (Inherited from Object.)

14 TrimExcess Sets the capacity to the actual number of elements in the Queue, if that number is less than 90 percent of current capacity.

Protected Methods:

S.No Name Description

1 Finalize Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

2 MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)

Stack Class:

Represents a variable size last-in-first-out (LIFO) collection of instances of the same arbitrary type.

Namespace: System.Collections.Generic Assembly: System (in system.dll)

Syntax:

[SerializableAttribute]

[ComVisibleAttribute(false)]

public class Stack<T> : IEnumerable<T>, ICollection, IEnumerable

Members: Public Properties

S.No Name Description

1 Count Gets the number of elements contained in the Stack.

Page 111: CSharp Handout v1.0

Handout - C#

Page 111 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Public Methods:

S.No Name Description 1 Clear Removes all objects from the Stack. 2 Contains Determines whether an element is in the Stack. 3 CopyTo Copies the Stack to an existing one-dimensional Array, starting at

the specified array index. 4 Equals Overloaded. Determines whether two Object instances are equal.

(Inherited from Object.) 5 GetEnumerator Returns an enumerator for the Stack. 6 GetHashCode Serves as a hash function for a particular type. GetHashCode is

suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

7 GetType Gets the Type of the current instance. (Inherited from Object.) 8 Peek Returns the object at the top of the Stack without removing it. 9 Pop Removes and returns the object at the top of the Stack. 10 Push Inserts an object at the top of the Stack. 11 ReferenceEquals Determines whether the specified Object instances are the same

instance. (Inherited from Object.) 12 ToArray Copies the Stack to a new array. 13 ToString Returns a String that represents the current Object. (Inherited from

Object.) 14 TrimExcess Sets the capacity to the actual number of elements in the Stack, if

that number is less than 90 percent of current capacity.

Protected Methods:

S.No Name Description

1 Finalize Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

2 MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)

Summary

Generics: Generics are classes, structures, interfaces, and methods that have placeholders (type parameters) for one or more of the types they store or use.

Generics Methods: A generic method is a method that is declared with type parameters.

Constraints: When define a generic class, We can apply restrictions to the kinds of types that client code can use for type arguments when it instantiates your class

Page 112: CSharp Handout v1.0

Handout - C#

Page 112 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Test Your Understanding

1. What is Generics? 2. How do you define Generics? 3. What are Constraints and how do you specify it? 4. What is Naked Type constraints and where it is used? 5. What is Generic method? 6. How do you declare Generic method? 7. What are the benefits of Generics?

Page 113: CSharp Handout v1.0

Handout - C#

Page 113 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 24: Generics and Collections

Learning Objectives

After completing this session, you will be able to: Explain the various collection objects as follows: o ArrayList

o List

o Queue

o Stack

o LinkedList

o Hashtable

o Dictionary

Collections

A collection is a set of similarly typed objects that are grouped together. Objects of any type can be grouped into a single collection of the type Object to take

advantage of constructs that are inherent in the language. For example, the C# foreach statement (for each in Visual Basic) expects all objects in the collection to be of a single type.

Closely related data can be handled more efficiently when grouped together into a collection. Instead of writing separate code to handle each individual object, you can use the same code to process all the elements of a collection.

To manage a collection, the Array class and the System.Collections classes are used to add, remove, and modify either individual elements of the collection or a range of elements. An entire collection can even be copied to another collection.

Defining Collections

Describes what collection types are, and some differences between generic and nongeneric collection types in the .NET Framework class library.

A collection is a set of similarly typed objects that are grouped together. Objects of any type can be grouped into a single collection of the type Object to take

advantage of constructs that are inherent in the language. For example, the C# foreach statement (for each in Visual Basic) expects all objects in the collection to be of a single type.

Commonly Used Collection Types

Collection types are the common variations of data collections, such as hash tables, queues, stacks, dictionaries, and lists.

Collections are based on the ICollection interface, the IList interface, the IDictionary interface, or their generic counterparts. The IList interface and the IDictionary interface are both derived from the ICollection interface; therefore, all collections are based on

Page 114: CSharp Handout v1.0

Handout - C#

Page 114 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

the ICollection interface either directly or indirectly. In collections based on the IList interface (such as Array, ArrayList, or List) or directly on the ICollection interface (such as Queue, Stack, or LinkedList), every element contains only a value.

In collections based on the IDictionary interface (such as the Hashtable and SortedList classes, or the Dictionary and SortedList generic classes), every element contains both a key and a value. The KeyedCollection class is unique because it is a list of values with keys embedded within the values, and, therefore, it behaves like a list and like a dictionary.

Generic collections are the best solution to strong typing. However, if your language does not support generics, the System.Collections namespace includes base collections, such as CollectionBase, ReadOnlyCollectionBase, and DictionaryBase, which are abstract base classes that can be extended to create collection classes that are strongly typed.

Creating and manipulating collection

The most common collections are provided by the .NET Framework. You can use any of them or create your own collection based on one of them. Each collection is designed for specific purposes. The members included in each System.Collections class reflect the purpose of the collection. In addition, the generic collections in System.Collections.Generic make it easy to create strongly typed collections.

When to use Generics collections

Using generic collections is generally recommended, because you gain the immediate benefit of type safety without having to derive from a base collection type and implement type-specific members. In addition, generic collection types generally perform better than the corresponding non-generic collection types (and better than types derived from nongeneric base collection types) when the collection elements are value types, because with generics there is no need to box the elements.

Classes in collections

The System.Collections namespace contains interfaces and classes that define various collections of objects. Some of them are as follows:

S.NO Class Description

1 ArrayList Implements the IList interface using an array whose size is dynamically increased as required.

2 Hashtable Represents a collection of key/value pairs that are organized based on the hash code of the key.

3 Queue Represents a first-in, first-out collection of objects.

4 Stack Represents a simple last-in-first-out (LIFO) non-generic collection of objects.

Page 115: CSharp Handout v1.0

Handout - C#

Page 115 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

ArrayList Class Implements the IList interface using an array whose size is dynamically increased as

required. Namespace:System.Collections

Assembly: mscorlib (in mscorlib.dll) Syntax:

[SerializableAttribute]

[ComVisibleAttribute(true)]

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

Members in ArrayList: Public properties:

S.No Name Description

1 Capacity Gets or sets the number of elements that the ArrayList can contain.

2 Count Gets the number of elements actually contained in the ArrayList.

3 IsFixedSize Gets a value indicating whether the ArrayList has a fixed size.

4 IsReadOnly Gets a value indicating whether the ArrayList is read-only.

5 IsSynchronized Gets a value indicating whether access to the ArrayList is synchronized (thread safe).

6 Item Gets or sets the element at the specified index.

7 SyncRoot Gets an object that can be used to synchronize access to the ArrayList.

Public methods:

S.No Name Description

1 Adapter Creates an ArrayList wrapper for a specific IList.

2 Add Adds an object to the end of the ArrayList.

3 AddRange Adds the elements of an ICollection to the end of the ArrayList.

4 BinarySearch Overloaded. Uses a binary search algorithm to locate a specific element in the sorted ArrayList or a portion of it.

5 Clear Removes all elements from the ArrayList.

6 Clone Creates a shallow copy of the ArrayList.

7 Contains Determines whether an element is in the ArrayList.

8 CopyTo Overloaded. Copies the ArrayList or a portion of it to a one-dimensional array.

Page 116: CSharp Handout v1.0

Handout - C#

Page 116 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

9 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

10 FixedSize Overloaded. Returns a list wrapper with a fixed size, where elements are allowed to be modified, but not added or removed.

11 GetEnumerator Overloaded. Returns an enumerator that iterates through the ArrayList.

12 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

13 GetRange Returns an ArrayList which represents a subset of the elements in the source ArrayList.

14 GetType Gets the Type of the current instance. (Inherited from Object.)

15 IndexOf Overloaded. Returns the zero-based index of the first occurrence of a value in the ArrayList or in a portion of it.

16 Insert Inserts an element into the ArrayList at the specified index.

17 InsertRange Inserts the elements of a collection into the ArrayList at the specified index.

18 LastIndexOf Overloaded. Returns the zero-based index of the last occurrence of a value in the ArrayList or in a portion of it.

19 ReadOnly Overloaded. Returns a list wrapper that is read-only.

20 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

21 Remove Removes the first occurrence of a specific object from the ArrayList.

22 RemoveAt Removes the element at the specified index of the ArrayList.

23 RemoveRange Removes a range of elements from the ArrayList.

24 Repeat Returns an ArrayList whose elements are copies of the specified value.

25 Reverse Overloaded. Reverses the order of the elements in the ArrayList or a portion of it.

26 SetRange Copies the elements of a collection over a range of elements in the ArrayList.

Page 117: CSharp Handout v1.0

Handout - C#

Page 117 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

27 Sort Overloaded. Sorts the elements in the ArrayList or a portion of it.

28 Synchronized Overloaded. Returns a list wrapper that is synchronized (thread safe).

29 ToArray Overloaded. Copies the elements of the ArrayList to a new array.

30 ToString Returns a String that represents the current Object. (Inherited from Object.)

31 TrimToSize Sets the capacity to the actual number of elements in the ArrayList.

Protected Methods

S.No Name Description

1 Finalize Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

2 MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)

HashTable Class:

Represents a collection of key/value pairs that are organized based on the hash code of the key.

Namespace:System.Collections Assembly: mscorlib (in mscorlib.dll)

Syntax:

[SerializableAttribute]

[ComVisibleAttribute(true)]

public class Hashtable : IDictionary, ICollection, IEnumerable,ISerializable, IDeserializationCallback, ICloneable

Members: Public properties:

S.No Name Description

1 Count Gets the number of key/value pairs contained in the Hashtable.

2 IsFixedSize Gets a value indicating whether the Hashtable has a fixed size.

3 IsReadOnly Gets a value indicating whether the Hashtable is read-only.

4 IsSynchronized Gets a value indicating whether access to the Hashtable is synchronized (thread safe).

5 Item Gets or sets the value associated with the specified key.

6 Keys Gets an ICollection containing the keys in the Hashtable.

Page 118: CSharp Handout v1.0

Handout - C#

Page 118 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

7 SyncRoot Gets an object that can be used to synchronize access to the Hashtable.

8 Values Gets an ICollection containing the values in the Hashtable.

Protected Properties:

S.No Name Description

1 comparer Gets or sets the IComparer to use for the Hashtable.

2 EqualityComparer Gets the IEqualityComparer to use for the Hashtable.

3 hcp Gets or sets the object that can dispense hash codes.

Public methods:

S.No Name Description 1 Add Adds an element with the specified key and value into the

Hashtable.

2 Clear Removes all elements from the Hashtable.

3 Clone Creates a shallow copy of the Hashtable.

4 Contains Determines whether the Hashtable contains a specific key.

5 ContainsKey Determines whether the Hashtable contains a specific key.

6 ContainsValue Determines whether the Hashtable contains a specific value.

7 CopyTo Copies the Hashtable elements to a one-dimensional Array instance at the specified index.

8 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

9 GetEnumerator Returns an IDictionaryEnumerator that iterates through the Hashtable.

10 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

11 GetObjectData Implements the ISerializable interface and returns the data needed to serialize the Hashtable.

12 GetType Gets the Type of the current instance. (Inherited from Object.)

13 OnDeserialization Implements the ISerializable interface and raises the deserialization event when the deserialization is complete.

Page 119: CSharp Handout v1.0

Handout - C#

Page 119 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description 14 ReferenceEquals Determines whether the specified Object instances are the same

instance. (Inherited from Object.)

15 Remove Removes the element with the specified key from the Hashtable.

16 Synchronized Returns a synchronized (thread safe) wrapper for the Hashtable.

17 ToString Returns a String that represents the current Object. (Inherited from Object.)

Protected Methods:

S.No Name Description

1 Finalize Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

2 GetHash Returns the hash code for the specified key.

3 KeyEquals Compares a specific Object with a specific key in the Hashtable.

4 MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)

Queue Class:

Represents a first-in, first-out collection of objects. Namespace:System.Collections

Assembly: mscorlib (in mscorlib.dll) Syntax:

[SerializableAttribute]

[ComVisibleAttribute(true)]

public class Queue : ICollection, IEnumerable, ICloneable

Members: Public properties:

S.No Name Description

1 Count Gets the number of elements contained in the Queue.

2 IsSynchronized Gets a value indicating whether access to the Queue is synchronized (thread safe).

3 SyncRoot Gets an object that can be used to synchronize access to the Queue.

Page 120: CSharp Handout v1.0

Handout - C#

Page 120 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Public Methods:

S.No Name Description

1 Clear Removes all objects from the Queue.

2 Clone Creates a shallow copy of the Queue.

3 Contains Determines whether an element is in the Queue.

4 CopyTo Copies the Queue elements to an existing one-dimensional Array, starting at the specified array index.

5 Dequeue Removes and returns the object at the beginning of the Queue.

6 Enqueue Adds an object to the end of the Queue.

7 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

8 GetEnumerator Returns an enumerator that iterates through the Queue.

9 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

10 GetType Gets the Type of the current instance. (Inherited from Object.)

11 Peek Returns the object at the beginning of the Queue without removing it.

12 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

13 Synchronized Returns a Queue wrapper that is synchronized (thread safe).

14 ToArray Copies the Queue elements to a new array.

15 ToString Returns a String that represents the current Object. (Inherited from Object.)

16 TrimToSize Sets the capacity to the actual number of elements in the Queue.

Protected methods:

S.No Name Description

1 Finalize Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

2 MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)

Page 121: CSharp Handout v1.0

Handout - C#

Page 121 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Stack Class: Represents a simple last-in-first-out (LIFO) non-generic collection of objects. Namespace:System.Collections

Assembly: mscorlib (in mscorlib.dll) Syntax:

[SerializableAttribute]

[ComVisibleAttribute(true)]

public class Stack : ICollection, IEnumerable, ICloneable

Members: Public properties:

S.No Name Description

1 Count Gets the number of elements contained in the Stack.

2 IsSynchronized Gets a value indicating whether access to the Stack is synchronized (thread safe).

3 SyncRoot Gets an object that can be used to synchronize access to the Stack.

Public methods:

S.No Name Description

1 Clear Removes all objects from the Stack.

2 Clone Creates a shallow copy of the Stack.

3 Contains Determines whether an element is in the Stack.

4 CopyTo Copies the Stack to an existing one-dimensional Array, starting at the specified array index.

5 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

6 GetEnumerator Returns an IEnumerator for the Stack.

7 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

8 GetType Gets the Type of the current instance. (Inherited from Object.)

9 Peek Returns the object at the top of the Stack without removing it.

10 Pop Removes and returns the object at the top of the Stack.

11 Push Inserts an object at the top of the Stack.

12 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

13 Synchronized Returns a synchronized (thread safe) wrapper for the Stack.

14 ToArray Copies the Stack to a new array.

15 ToString Returns a String that represents the current Object. (Inherited from Object.)

Page 122: CSharp Handout v1.0

Handout - C#

Page 122 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Protected methods:

S.No Name Description

1 Finalize Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

2 MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)

Summary

A collection is a set of similarly typed objects that are grouped together. Collection types are the common variations of data collections, such as hash tables,

queues, stacks, dictionaries, and lists.

Test Your Understanding

1. What are collections? 2. What are the namespaces used for collections? 3. What are the types of collections used? 4. Distinguish between dictionary and sorted dictionary. 5. What is the functionality of stack? 6. Sate the difference between stack and a queue. 7. What are the methods used in HashTable?

Page 123: CSharp Handout v1.0

Handout - C#

Page 123 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 27: Exception Handling

Learning Objectives

After completing the session, you will be able to: Explain Exception handling in C#

Exception handling in C#

C# handles errors and abnormal conditions with exceptions. An exception is an object that encapsulates information about an unusual program occurrence, such as running out of memory or losing a network connection. When an exceptional circumstance arises, an exception is thrown. You might decide to throw an exception in our methods (for example, if you find an invalid parameter has been provided), these popularly known as Application exceptions. You provide for the possibility of exceptions by adding try/catch blocks in the program. The catch blocks are also called exception handlers. The idea is that we try potentially dangerous code, and if an exception is thrown we catch the exception in the catch block and handle the situation appropriately. Ideally, after the exception is caught the program can fix the problem and continue or you can print a meaningful error message and terminate gracefully. try

{ // Code where we are anticipating the Exception

}

catch (Exception)

{ //Do Nothing

// Just Eat Away the Exception

}

When a program encounters an exceptional circumstance, such as running out of memory, it throws (or raises) an exception. The runtime will search for an appropriate exception handler, like in the following example, if the file is not found and hence FileNotFound Exception will be thrown and it will be handled by the FileNotFoundException catch block, if there was any other IO related exception, it will be handled by the IOException catch block and if there was some other exception it will be handled by the generic Exception catch block. try

{ //trying to access a secured file

}

catch(FileNotFoundException e1)

{

//handle FileNotFoundException

}

catch(IOException e2)

{

//handle IOException

Page 124: CSharp Handout v1.0

Handout - C#

Page 124 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

}

catch(Exception e3)

{ //handle generic exception

}

The order of the catch block is very important, if for example the same catch block was arranged as follows, even if there was a FileNotFoundException, it will be handled by generic IO exception catch block as it is placed in front of the FileNotFoundException handling block. try

{ //trying to access a secured file

}

catch(IOException e1)

{ //handle IOException

}

catch(FileNotFoundException e2)

{ //handle FileNotFoundException

}

catch(Exception e3)

{ //handle generic exception

}

The search for an exception handler will also unwind the stack i.e. if the currently running function does not handle the exception, the current function terminates and the calling function gets a chance to handle the exception. If none of the calling functions handles it, the exception ultimately is handled by the Common Language Runtime (CLR), which abruptly terminates the program. private void Method()

{

try

{ //Invoke MethodA

MethodA();

}

catch( SecurityException ex)

{

// handle gracefully the access denied scenario

}

}

private void MethodB()

{ //Invoke MethodA

MethodB();

}

private void MethodB()

{ //trying to access a secured file

//An exception here will bubble up the stack to Method()

}

Page 125: CSharp Handout v1.0

Handout - C#

Page 125 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Throw Statement

To signal an abnormal condition in a C# program, throw an exception by using the throw keyword. The following line of code creates a new instance of System.Exception and then throws it, similary you can also throw any specific exceptions. throw new Exception(“There is an unhandled situation”);

Finally Statement

In some instances, throwing an exception and unwinding the stack can create a problem. For example, if you opened, you might need an opportunity to close the file or flush the buffer. If there is some action that must be made regardless of whether an exception is thrown, such as closing a file. One approach is to enclose the dangerous action in a try block and then to perform the necessary action (close the file) in both the catch and try blocks. However, this is an ugly duplication of code, and its error prone. C# provides a better alternative in the finally block. You create a finally block with the keyword finally, and enclose the block in braces. The code in the finally block is guaranteed to be executed regardless of whether an exception is thrown. private void Create Customer() {

try

{ // open a db connection and perform some operation

}

catch(Exception e)

{ //log and clean-up code

}

finally

{

//close the db connection

}

}

A finally block can be created with or without catch blocks, but a finally block requires a try block to execute. In the following scenario, the finally block will get executed before the exception is handled somewhere higher in the stack call. private void CreateCustomer() {

try

{ // open a db connection and perform some operation

}

finally

{ //close the db connection

}

}

Page 126: CSharp Handout v1.0

Handout - C#

Page 126 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

User Defined Exceptions

C# allows creating user defined exception class and this class should be derived from Exception base class. So the user-defined exception classes must inherit from either Exception class or one of its standard derived classes. Using System;

class UserDefinedException : Exception

{

Public MyException( string str)

{

Console.WriteLine("User defined exception");

}

}

Exception Type

There are two types of exceptions: Application Exception System Exception

Application Exception User applications, not the common language runtime, throw custom exceptions derived from the Application Exception class. The Application Exception class differentiates between exceptions defined by applications versus exceptions defined by the system. If you are designing an application that needs to create its own exceptions, then you are advised to derive custom exceptions from the Exception class. It was originally thought that custom exceptions should derive from the Application Exception class; however in practice this has not been found to add significant value Public Constructors:

S.No Name Description

1 ExceptionCollection Initializes a new instance of the ExceptionCollection class.

Public Properties:

S.No Name Description

1 Data Gets a collection of key/value pairs that provide additional, user-defined information about the exception.(Inherited from Exception.)

2 Exceptions Gets the array of Exception objects that represent the collection of exceptions.

3 HelpLink Gets or sets a link to the help file associated with this exception.(Inherited from Exception.)

4 InnerException Gets the Exception instance that caused the current exception.(Inherited from Exception.)

Page 127: CSharp Handout v1.0

Handout - C#

Page 127 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

5 Message Gets a message that describes the current exception.(Inherited from Exception.)

6 Source Gets or sets the name of the application or the object that causes the error.(Inherited from Exception.)

7 StackTrace Gets a string representation of the frames on the call stack at the time the current exception was thrown.(Inherited from Exception.)

8 TargetSite Gets the method that throws the current exception.(Inherited from Exception.)

Protected Properties

S.No Name Description

1 HResult Gets or sets HRESULT, a coded numerical value that is assigned to a specific exception. (Inherited from Exception.)

Public Methods

S.No Name Description

1 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

2 GetBaseException When overridden in a derived class, returns the Exception that is the root cause of one or more subsequent exceptions. (Inherited from Exception.)

3 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

4 GetObjectData Overridden. Populates a SerializationInfo with the data needed to serialize the ExceptionCollection.

5 GetType Gets the runtime type of the current instance. (Inherited from Exception.)

6 Reference Equals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

7 ToString Creates and returns a string representation of the current exception. (Inherited from Exception.)

Protected Methods:

S.No Name Description

1 Finalize Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

2 MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)

Page 128: CSharp Handout v1.0

Handout - C#

Page 128 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

System Exception Represents errors that occur during application execution. This is the base class for all exceptions. The following table describes some of the system exceptions:

Summary

Overview of Exceptions: C# provides three keywords try, catch and finally to do exception handling.

Exception Class: The System.Exception Class is small class representing information about the kind of Exception.

Exception Class Properties are Message, source, stacktrace, targetsite, helplink, InnerException

Exception Hierarchy: o SystemExceptions: The CLR generates SystemExceptions, which can occur at

any point during program execution o ApplicationException: It is a base class that programmers can extend to create

exception classes that are specific to their applications

Page 129: CSharp Handout v1.0

Handout - C#

Page 129 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Test your Understanding

1. What do you understand by Exception class? 2. State some features about Exception properties. 3. Differentiate between System Exceptions and User defined Exceptions. 4. Describe some system exceptions. 5. Give program samples for using multiple exceptions with throw and finally statements.

Page 130: CSharp Handout v1.0

Handout - C#

Page 130 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 30: File Handling

Learning Objectives

After completing this session, you will be able to: Read and write in a Text File Read from a Stream File Describe opening and appending in Log File Work with StreamReader and StreamWriter

Stream Class

The abstract base class Stream supports reading and writing bytes. Stream integrates asynchronous support. Its default implementations define synchronous reads and writes in terms of their corresponding asynchronous methods, and vice versa. All classes that represent streams inherit from the Stream class. Public Properties:

S.No Name Description

1 CanRead When overridden in a derived class, gets a value indicating whether the current stream supports reading.

2 CanSeek When overridden in a derived class, gets a value indicating whether the current stream supports seeking.

3 CanTimeout Gets a value that determines whether the current stream can time out.

4 CanWrite When overridden in a derived class, gets a value indicating whether the current stream supports writing.

5 Length When overridden in a derived class, gets the length in bytes of the stream.

6 Position When overridden in a derived class, gets or sets the position within the current stream.

7 ReadTimeout Gets or sets a value that determines how long the stream will attempt to read before timing out.

8 WriteTimeout Gets or sets a value that determines how long the stream will attempt to write before timing out.

Page 131: CSharp Handout v1.0

Handout - C#

Page 131 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Public Methods:

S.No Name Description

1 BeginRead Begins an asynchronous read operation.

2 BeginWrite Begins an asynchronous write operation.

3 Close Closes the current stream and releases any resources (such as sockets and file handles) associated with the current stream.

4 CreateObjRef Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object. (Inherited from MarshalByRefObject.)

5 Dispose Overloaded. Releases all resources used by the Stream object.

6 EndRead Waits for the pending asynchronous read to complete.

7 EndWrite Ends an asynchronous write operation.

8 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

9 Flush When overridden in a derived class, clears all buffers for this stream and causes any buffered data to be written to the underlying device.

10 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

11 GetLifetimeService Retrieves the current lifetime service object that controls the lifetime policy for this instance. (Inherited from MarshalByRefObject.)

12 GetType Gets the Type of the current instance. (Inherited from Object.)

13 InitializeLifetimeService Obtains a lifetime service object to control the lifetime policy for this instance. (Inherited from MarshalByRefObject.)

14 Read When overridden in a derived class reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.

15 ReadByte Reads a byte from the stream and advances the position within the stream by one byte or returns 1 if at the end of the stream.

16 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

17 Seek When overridden in a derived class, sets the position within the current stream.

Page 132: CSharp Handout v1.0

Handout - C#

Page 132 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

18 SetLength When overridden in a derived class, sets the length of the current stream.

19 Synchronized Creates a thread-safe (synchronized) wrapper around the specified Stream object.

20 ToString Returns a String that represents the current Object. (Inherited from Object.)

21 Write When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.

22 WriteByte Writes a byte to the current position in the stream and advances the position within the stream by one byte.

Binary Reader

Reads primitive data types as binary values in a specific encoding. Public properties:

S.No Name Description

1 BaseStream Exposes access to the underlying stream of the BinaryReader.

Public Methods:

S.No Name Description

1 Close Closes the current reader and the underlying stream.

2 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

3 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

4 GetType Gets the Type of the current instance. (Inherited from Object.)

5 PeekChar Returns the next available character and does not advance the byte or character position.

6 Read Overloaded. Reads characters from the underlying stream and advances the current position of the stream.

7 ReadBoolean Reads a Boolean value from the current stream and advances the current position of the stream by one byte.

8 ReadByte Reads the next byte from the current stream and advances the current position of the stream by one byte.

9 ReadBytes Reads count bytes from the current stream into a byte array and advances the current position by count bytes.

Page 133: CSharp Handout v1.0

Handout - C#

Page 133 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

10 ReadChar Reads the next character from the current stream and advances the current position of the stream in accordance with the Encoding used and the specific character being read from the stream.

11 ReadChars Reads count characters from the current stream, returns the data in a character array, and advances the current position in accordance with the Encoding used and the specific character being read from the stream.

12 ReadDecimal Reads a decimal value from the current stream and advances the current position of the stream by sixteen bytes.

13 ReadDouble Reads an 8-byte floating point value from the current stream and advances the current position of the stream by eight bytes.

14 ReadInt16 Reads a 2-byte signed integer from the current stream and advances the current position of the stream by two bytes.

15 ReadInt32 Reads a 4-byte signed integer from the current stream and advances the current position of the stream by four bytes.

16 ReadInt64 Reads an 8-byte signed integer from the current stream and advances the current position of the stream by eight bytes.

17 ReadSByte Reads a signed byte from this stream and advances the current position of the stream by one byte.

18 ReadSingle Reads a 4-byte floating point value from the current stream and advances the current position of the stream by four bytes.

19 ReadString Reads a string from the current stream. The string is prefixed with the length, encoded as an integer seven bits at a time.

20 ReadUInt16 Reads a 2-byte unsigned integer from the current stream using little endian encoding and advances the position of the stream by two bytes.

21 ReadUInt32 Reads a 4-byte unsigned integer from the current stream and advances the position of the stream by four bytes.

22 ReadUInt64 Reads an 8-byte unsigned integer from the current stream and advances the position of the stream by eight bytes.

23 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

24 ToString Returns a String that represents the current Object. (Inherited from Object.)

Binary Writer

Writes primitive types in binary to a stream and supports writing strings in a specific encoding. Public Fields:

S.No Name Description

1 Null Specifies a BinaryWriter with no backing store.

Page 134: CSharp Handout v1.0

Handout - C#

Page 134 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Public Properties:

S.No Name Description

1 BaseStream Gets the underlying stream of the BinaryWriter.

Public Methods:

S.No Name Description

1 Close Closes the current BinaryWriter and the underlying stream.

2 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

3 Flush Clears all buffers for the current writer and causes any buffered data to be written to the underlying device.

4 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

5 GetType Gets the Type of the current instance. (Inherited from Object.)

6 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

7 Seek Sets the position within the current stream.

8 ToString Returns a String that represents the current Object. (Inherited from Object.)

9 Write Overloaded. Writes a value to the current stream.

Text Reader

Represents a reader that can read a sequential series of characters. Public fields:

S.No Name Description

1 Null Provides a TextReader with no data to read from.

Public Methods:

S.No Name Description

1 Close Closes the TextReader and releases any system resources associated with the TextReader.

2 CreateObjRef Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object. (Inherited from MarshalByRefObject.)

3 Dispose Overloaded. Releases all resources used by the TextReader object.

4 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

Page 135: CSharp Handout v1.0

Handout - C#

Page 135 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

5 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

6 GetLifetimeService Retrieves the current lifetime service object that controls the lifetime policy for this instance. (Inherited from MarshalByRefObject.)

7 GetType Gets the Type of the current instance. (Inherited from Object.)

8 InitializeLifetimeService Obtains a lifetime service object to control the lifetime policy for this instance. (Inherited from MarshalByRefObject.)

9 Peek Reads the next character without changing the state of the reader or the character source. Returns the next available character without actually reading it from the input stream.

10 Read Overloaded. Reads data from an input stream.

11 ReadBlock Reads a maximum of count characters from the current stream and writes the data to buffer, beginning at index.

12 ReadLine Reads a line of characters from the current stream and returns the data as a string.

13 ReadToEnd Reads all characters from the current position to the end of the TextReader and returns them as one string.

14 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

15 Synchronized Creates a thread-safe wrapper around the specified TextReader.

16 ToString Returns a String that represents the current Object. (Inherited from Object.)

This program demonstrates about Text Reader Class: using System;

using System.IO;

class TextRW

{

static void Main()

{

TextWriter stringWriter = new StringWriter();

using(TextWriter streamWriter =

new StreamWriter("InvalidPathChars.txt"))

Page 136: CSharp Handout v1.0

Handout - C#

Page 136 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

{

WriteText(stringWriter);

WriteText(streamWriter);

}

TextReader stringReader =

new StringReader(stringWriter.ToString());

using(TextReader streamReader =

new StreamReader("InvalidPathChars.txt"))

{

ReadText(stringReader);

ReadText(streamReader);

}

}

static void WriteText(TextWriter textWriter)

{

textWriter.Write("Invalid file path characters are: ");

textWriter.Write(Path.InvalidPathChars);

textWriter.Write('.');

}

static void ReadText(TextReader textReader)

{

Console.WriteLine("From {0} - {1}",

textReader.GetType().Name, textReader.ReadToEnd());

}

}

Text Writer

Represents a writer that can write a sequential series of characters. This class is abstract. Public fields:

S.No Name Description

1 Null Provides a TextWriter with no backing store that can be written to, but not read from.

Public Properties:

S.No Name Description

1 Encoding When overridden in a derived class, returns the Encoding in which the output is written.

2 FormatProvider Gets an object that controls formatting.

3 NewLine Gets or sets the line terminator string used by the current TextWriter.

Page 137: CSharp Handout v1.0

Handout - C#

Page 137 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Public Methods:

S.No Name Description

1 Close Closes the current writer and releases any system resources associated with the writer.

2 CreateObjRef Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object. (Inherited from MarshalByRefObject.)

3 Dispose Overloaded. Releases all resources used by the TextWriter object.

4 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

5 Flush Clears all buffers for the current writer and causes any buffered data to be written to the underlying device.

6 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

7 GetLifetimeService Retrieves the current lifetime service object that controls the lifetime policy for this instance. (Inherited from MarshalByRefObject.)

8 GetType Gets the Type of the current instance. (Inherited from Object.)

9 InitializeLifetimeService Obtains a lifetime service object to control the lifetime policy for this instance. (Inherited from MarshalByRefObject.)

10 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

11 Synchronized Creates a thread-safe wrapper around the specified TextWriter.

12 ToString Returns a String that represents the current Object. (Inherited from Object.)

13 Write Overloaded. Writes the given data type to a text stream.

14 WriteLine Overloaded. Writes some data as specified by the overloaded parameters, followed by a line terminator.

Page 138: CSharp Handout v1.0

Handout - C#

Page 138 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

This program demonstrates about TextWriter Class: using System;

using System.IO;

class TextRW

{

static void Main()

{

TextWriter stringWriter = new StringWriter();

using(TextWriter streamWriter =

new StreamWriter("InvalidPathChars.txt"))

{

WriteText(stringWriter);

WriteText(streamWriter);

}

TextReader stringReader =

new StringReader(stringWriter.ToString());

using(TextReader streamReader =

new StreamReader("InvalidPathChars.txt"))

{

ReadText(stringReader);

ReadText(streamReader);

}

}

static void WriteText(TextWriter textWriter)

{

textWriter.Write("Invalid file path characters are: ");

textWriter.Write(Path.InvalidPathChars);

textWriter.Write('.');

}

static void ReadText(TextReader textReader)

{

Console.WriteLine("From {0} - {1}",

textReader.GetType().Name, textReader.ReadToEnd());

}

}

Page 139: CSharp Handout v1.0

Handout - C#

Page 139 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

File I/O Operations

.NET provides a FileStream class to read from, write to, open, and close files on a file system, as well as to manipulate other file-related operating system handles such as pipes, standard input, and standard output. You can specify read and write operations to be either synchronous or asynchronous. FileStream buffers input and output for better performance. FileStream objects support random access to files using the Seek method. Seek allows the read/write position to be moved to any position within the file.

Stream Reader Class

Implements a TextReader that reads characters from a byte stream in a particular encoding. Public Fields:

S.No Name Description

1 Null A StreamReader object around an empty stream.

Public properties:

S.No Name Description

1 BaseStream Returns the underlying stream.

2 CurrentEncoding Gets the current character encoding that the current StreamReader object is using.

3 EndOfStream Gets a value that indicates whether the current stream position is at the end of the stream.

Public Methods:

S.No Name Description

1 Close Overridden. Closes the StreamReader object and the underlying stream, and releases any system resources associated with the reader.

2 CreateObjRef Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object. (Inherited from MarshalByRefObject.)

3 DiscardBufferedData Allows a StreamReader object to discard its current data.

4

Dispose Overloaded.

5 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

6 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

Page 140: CSharp Handout v1.0

Handout - C#

Page 140 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

7 GetLifetimeService Retrieves the current lifetime service object that controls the lifetime policy for this instance. (Inherited from MarshalByRefObject.)

8 GetType Gets the Type of the current instance. (Inherited from Object.)

9 InitializeLifetimeService Obtains a lifetime service object to control the lifetime policy for this instance. (Inherited from MarshalByRefObject.)

10 Peek Overridden. Returns the next available character but does not consume it.

11 Read Overloaded. Overridden. Reads the next character or next set of characters from the input stream.

12 ReadBlock Reads a maximum of count characters from the current stream and writes the data to buffer, beginning at index. (Inherited from TextReader.)

13 ReadLine Overridden. Reads a line of characters from the current stream and returns the data as a string.

14 ReadToEnd Overridden. Reads the stream from the current position to the end of the stream.

15 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

16 Synchronized Creates a thread-safe wrapper around the specified TextReader. (Inherited from TextReader.)

17 ToString Returns a String that represents the current Object. (Inherited from Object.)

Stream Writer Class

Implements a TextWriter for writing characters to a stream in a particular encoding. Public fields:

S.No Name Description

1 Null Provides a StreamWriter with no backing store that can be written to, but not read from.

Public properties:

S.No Name Description

1 AutoFlush Gets or sets a value indicating whether the StreamWriter will flush its buffer to the underlying stream after every call to StreamWriter.Write.

2 BaseStream Gets the underlying stream that interfaces with a backing store.

3 Encoding Overridden. Gets the Encoding in which the output is written.

Page 141: CSharp Handout v1.0

Handout - C#

Page 141 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

S.No Name Description

4 FormatProvider Gets an object that controls formatting.(Inherited from TextWriter.)

5 NewLine Gets or sets the line terminator string used by the current TextWriter.(Inherited from TextWriter.)

Public Methods:

S.No Name Description

1 Close Overridden. Closes the current StreamWriter object and the underlying stream.

2 CreateObjRef Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object. (Inherited from MarshalByRefObject.)

3 Dispose Overloaded.

4 Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

5 Flush Overridden. Clears all buffers for the current writer and causes any buffered data to be written to the underlying stream.

6 GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

7 GetLifetimeService Retrieves the current lifetime service object that controls the lifetime policy for this instance. (Inherited from MarshalByRefObject.)

8 GetType Gets the Type of the current instance. (Inherited from Object.)

9 InitializeLifetimeService Obtains a lifetime service object to control the lifetime policy for this instance. (Inherited from MarshalByRefObject.)

10 ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

11 Synchronized Creates a thread-safe wrapper around the specified TextWriter. (Inherited from TextWriter.)

12 ToString Returns a String that represents the current Object. (Inherited from Object.)

13 Write Overloaded. Writes to the stream.

14 WriteLine Overloaded. Writes some data as specified by the overloaded parameters, followed by a line terminator. (Inherited from TextWriter.)

Page 142: CSharp Handout v1.0

Handout - C#

Page 142 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Summary

Text File: It is a file in which you can read or write the data using stream reader and stream writer.

Stream: Stream is used to either write or read in to file. It is broadly classified into the following o readBuffer() o readLastBuffer() o writeBuffer() o writeLastBuffer()

Log File: It is a text file consisting of time stamped status and error messages, detailing the operational history of a given piece of software.

Stream Reader and Writer: It read and writes characters from a byte stream in a particular encoding.

Test Your Understanding

1. What is the purpose of stream writer? 2. What is the purpose of stream reader? 3. What you mean by log file?

Page 143: CSharp Handout v1.0

Handout - C#

Page 143 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 32: XML and .Net Framework

Learning Objectives

After completing the session, you will be able to: Explain System.Xml assembly and its supported standards Identify how to avoid Name conflicts using namespaces Define XMLTextReader class Identify how to validate the XML document by using of XMLvalidatingReader class Explain XMLTextWriter class and XMLDocument class

XML

The design goals for the XML classes in the .NET Framework are: High-productivity. Standards-based. Multilingual support. Extensible. Pluggable architecture. Focused on performance, reliability, and scalability. Integration with ADO.NET.

The .NET Framework provides an opportunity to design an integrated suite of XML classes and also show innovation in the XML world. The XML classes provided are core elements of the .NET Framework. These classes provide an open, standards-compliant, interoperable solution to the challenges that developers face today. For more information on the suite of classes in XML in the .NET Framework, see the System.Xml, System.Xml.XPath, System.Xml.Xsl, and System.Xml.Schema namespaces. The goals of XML in .NET Framework are as follows:

Compliance with the W3C standards. Extensibility. Pluggable architecture. Performance. Tight integration with ADO.NET.

Standards Compliance

Standards compliance means that the classes fully conform to the current W3C recommended standards of XML, Namespaces, XSLT, XPath, Schema, and the Document Object Model (DOM). Compliance ensures interoperability and eases application development across platforms.

Page 144: CSharp Handout v1.0

Handout - C#

Page 144 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Most notably, the XML classes in .NET Framework supports the W3C XML Schema Definition language (XSD) 1.0 recommendation. There are XML classes in the .NET Framework that provide validation, and an object model is available to build the XSD Schemas in memory. The fast, forward-only parser that can validate against XML Schemas and DTDs is called the XmlReader. The XmlReader is a compliant XML parser. The XmlSchemaSet class can be use to cache frequently used XML Schemas. There are a set of XML classes in the .NET Framework that provide a Schema Object Model (SOM) that allows you to programmatically build and compile XSD schemas. The XmlSchema class represents an XSD schema. These schemas can be loaded and persisted using the XmlReader and XmlWriter classes. The XmlDocument class implements the Document Object Model level 1 and level 2 recommendations and is tailored to the common design guidelines of the .NET Framework. For example, the method names are capitalized. The XslCompiledTransform class conforms to the XSL Transformations (XSLT) Version 1.0 recommendation and the XML Path Language (XPath) 1.0 recommendation for transforming documents using XSLT.

Extensibility

The XML classes in the .NET Framework are designed to be extensible through the use of abstract base classes and virtual methods. This extensibility is illustrated by the XmlResolver class. The XmlResolver class is an abstract class that resolves XML resources such as entities, import or export elements, and so on. The XmlUrlResolver and XmlSecureResolver classes are implementations of the XmlResolver class. You can create a customized version of the XmlResolver class by deriving from the XmlResolver class or any of its implementations.

Pluggable Architecture

XML in the .NET Framework has a pluggable architecture. Pluggable, in this stream-based architecture, means that components that are based on these abstract classes within the .NET Framework can be easily substituted. Pluggable architecture also means that data can be streamed between the components, and new components inserted into this stream can alter the processing.

Performance

The XML classes in the .NET Framework represent low-level XML processing components that are used, not only as part of the .NET Framework, but to integrate XML into applications.

Integration with ADO.NET

Relational data and XML are brought together in the .NET Framework by a tight integration between the XML classes and ADO.NET.

Page 145: CSharp Handout v1.0

Handout - C#

Page 145 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Architecture Summary of XML in .Net Framework

The XML classes in the .NET Framework represent a coherently designed and integrated set of classes that enable you to easily build XML aware applications. The goals outlined in the previous section address real world issues that developers face when using XML: not only to build Web orientated applications, but all the other areas that XML addresses such as a common serialization format, object representation, interoperability and messaging, to name a few.

Stream-Based XML Parsing

The XmlReader class defines provides fast, non-cached, forward-only access to XML data. XmlReader objects are created using the System.Xml.XmlReader.Create method. The XmlReaderSettings class allows you to specify the set of features to enable on the created XmlReader object.

Stream-Based XML Creation

The XmlWriter class provides a non-cached, forward-only means of generating streams or files containing XML data. XmlWriter objects are created using the System.Xml.XmlWriter.Create method. The XmlWriterSettings class allows you to specify the set of features to enable on the created XmlWriter object.

In-Memory XML Processing

The .NET Framework provides two classes that can be used for processing XML data in-memory.

XPathNavigator Class

The XPathNavigator class offers several editing options and navigation capabilities using a cursor model over XML documents. The XML documents can be contained in an XPathDocument or an XmlDocument object.

XmlDocument Class

The XmlDocument, and its related classes, is based on the W3C Document Object Model (DOM). The DOM provides full-fidelity, such as preserving white space and multiple text nodes. Nodes can be created, inserted, removed, and modified using methods and properties based on the familiar DOM model.

Process XML Data In-Memory

The Microsoft .NET Framework includes two models for processing XML data. The XmlDocument class implements the W3C Document Object Model (DOM) Level 1 Core and the Core DOM Level 2 recommendations. The DOM is an in-memory (cache) tree representation of an XML document. With the XmlDocument, and its related classes, you can construct XML documents, load and access data, modify data, and save changes. The XPathDocument class is read-only, in-memory data store that is based on the XPath data model. The XPathNavigator class offers several editing options and navigation capabilities using a cursor model over XML documents contained in the read-only XPathDocument class as well as the XmlDocument class.

Page 146: CSharp Handout v1.0

Handout - C#

Page 146 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

XML Document Object Model

The XML Document Object Model (DOM) class is an in-memory representation of an XML document. The DOM allows you to programmatically read, manipulate, and modify an XML document.

Mapping the Object Hierarchy to XML Data

When an XML document is in memory, the conceptual representation is a tree. For programming, you have an object hierarchy to access the nodes of the tree. The following example shows you how the XML content becomes nodes. As the XML is read into the XML Document Object Model (DOM), the pieces are translated into nodes, and these nodes retain additional metadata about themselves, such as their node type and values. The node type is its object and is what determines what actions can be performed and what properties can be set or retrieved. If you have the following simple XML: <book>

<title>The Handmaid's Tale</title>

</book>

The input is represented in memory as the following node tree with the assigned node type property: Book and title node tree representation:

The book element becomes an XmlElement object, the next element, title, also becomes an XmlElement, while the element content becomes an XmlText object. In looking at the XmlElement methods and properties, the methods and properties are different than the methods and properties available on an XmlText object. So knowing what node type the XML markup becomes is vital, as its node type determines the actions that can be performed.

Page 147: CSharp Handout v1.0

Handout - C#

Page 147 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

XML Document Creation

There are two ways to create an XML document. One way is to create an XmlDocument with no parameters. The other way is to create an XmlDocument and pass it an XmlNameTable as a parameter. The following example shows how to create a new, empty XmlDocument using no parameters. XmlDocument doc = new XmlDocument();

Once a document is created, you can load it with data from a string, stream, URL, text reader, or an XmlReader derived class using the Load method. There is also another load method, the LoadXML method, which reads XML from a string.

Reading an XML Document into the DOM

XML information is read into memory from different formats. It can be read from a string, stream, URL, text reader, or a class derived from the XmlReader. The Load method brings the document into memory and has overloaded methods available to take data from each of the different formats. There is also a LoadXml method that reads XML from a string. The following example shows XML being loaded with the LoadXml method and the data subsequently saved to a text file called data.xml. using System;

using System.IO;

using System.Xml;

public class Sample

{

public static void Main()

{

// Create the XmlDocument.

XmlDocument doc = new XmlDocument();

doc.LoadXml("<book genre='novel' ISBN='1-861001-57-5'>" +

"<title>Pride And Prejudice</title>" +

"</book>");

// Save the document to a file.

doc.Save("data.xml");

}

}

Accessing Attributes in the DOM

Attributes are properties of the element, not children of the element. This distinction is important because of the methods used to navigate sibling, parent, and child nodes of the XML Document Object Model (DOM). For example, the PreviousSibling and NextSibling methods are not used to navigate from an element to an attribute or between attributes. Instead, an attribute is a property of

Page 148: CSharp Handout v1.0

Handout - C#

Page 148 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

an element and is owned by an element, has an OwnerElement property and not a parentNode property, and has distinct methods of navigation. The following code example shows how to retrieve an attribute collection and, using the Count method for the looping index, iterate over it. The code then shows how to retrieve a single attribute from the collection and display its value. using System;

using System.IO;

using System.Xml;

public class Sample

{

public static void Main()

{

XmlDocument doc = new XmlDocument();

doc.LoadXml("<book genre='novel' ISBN='1-861001-57-5' misc='sale item'>" +

"<title>The Handmaid's Tale</title>" +

"<price>14.95</price>" +

"</book>");

// Move to an element.

XmlElement myElement = doc.DocumentElement;

// Create an attribute collection from the element.

XmlAttributeCollection attrColl = myElement.Attributes;

// Show the collection by iterating over it.

Console.WriteLine("Display all the attributes in the collection...");

for (int i = 0; i < attrColl.Count; i++)

{

Console.Write("{0} = ", attrColl[i].Name);

Console.Write("{0}", attrColl[i].Value);

Console.WriteLine();

}

// Retrieve a single attribute from the collection; specifically, the

// attribute with the name "misc".

XmlAttribute attr = attrColl["misc"];

// Retrieve the value from that attribute.

String miscValue = attr.InnerXml;

Page 149: CSharp Handout v1.0

Handout - C#

Page 149 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Console.WriteLine("Display the attribute information.");

Console.WriteLine(miscValue);

}

}

Output:

Display all the attributes in the collection.

genre = novel

ISBN = 1-861001-57-5

misc = sale item

Display the attribute information.

sale item

Reading XML with the XmlReader

The XmlReader class is an abstract base class that provides non-cached, forward-only, read-only access to XML data. It conforms to the W3C Extensible Markup Language (XML) 1.0 and the Namespaces in XML recommendations. The XmlReader class supports reading XML data from a stream or file. It defines methods and properties that allow you to move through the data and read the contents of a node. The current node refers to the node on which the reader is positioned. The reader is advanced using any of the read methods and properties return the value of the current node. The XmlReader class enables you to:

Verify that the characters are legal XML characters, and that element and attribute names are valid XML names.

Verify that the XML document is well formed. Validate the data against a DTD or schema. Retrieve data from the XML stream or skip unwanted records using a pull model.

The following table describes the methods and properties that the XmlReader class provides for processing elements. After the XmlReader is positioned on an element, the node properties, such as Name, reflect the element values. In addition to the members described below, any of the general methods and properties of the XmlReader class can also be used to process elements. For example, you can use the ReadInnerXml method to read the contents of an element.

Member name Description

IsStartElement Checks if the current node is a start tag or an empty element tag.

ReadStartElement Checks that the current node is an element and advances the reader to the next node.

Page 150: CSharp Handout v1.0

Handout - C#

Page 150 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Member name Description

ReadEndElement Checks that the current node is an end tag and advances the reader to the next node.

ReadElementString Reads a text-only element.

ReadToDescendant Advances the XmlReader to the next descendant element with the specified name.

ReadToNextSibling Advances the XmlReader to the next sibling element with the specified name.

IsEmptyElement

Checks if the current element has an empty element tag. This property enables you to determine the difference between the following: <item num="123"/> (IsEmptyElement is true.) <item num="123"> (IsEmptyElement is false, although element content is empty.) In other words, IsEmptyElement simply reports whether or not the element in the source document has an end element tag.

using (XmlReader reader = XmlReader.Create("book3.xml")) {

// Parse the XML document. ReadString is used to

// read the text content of the elements.

reader.Read();

reader.ReadStartElement("book");

reader.ReadStartElement("title");

Console.Write("The content of the title element: ");

Console.WriteLine(reader.ReadString());

reader.ReadEndElement();

reader.ReadStartElement("price");

Console.Write("The content of the price element: ");

Console.WriteLine(reader.ReadString());

reader.ReadEndElement();

reader.ReadEndElement();

}

Writing XML with the XmlWriter

The XmlWriter class is an abstract base class that provides a forward-only, write-only, non-cached way of generating XML streams. It can be used to build XML documents that conform to the W3C Extensible Markup Language (XML) 1.0 (Second Edition) (www.w3.org/TR/2000/REC-xml-20001006.html) recommendation and the Namespaces in XML recommendation (www.w3.org/TR/REC-xml-names/).

Page 151: CSharp Handout v1.0

Handout - C#

Page 151 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

The XmlWriter enables you to: Verify that the characters are legal XML characters and that element and attribute

names are valid XML names. Verify that the XML document is well-formed. Encode binary bytes as Base64, or BinHex, and write out the resulting text. Pass values using common language runtime types rather than strings. This allows

avoid having to manually perform value conversions. Write multiple documents to one output stream. Write valid names, qualified names, and name tokens.

The XmlTextWriter, derived from the XmlWriter, writes XML to a file, console, stream, and other output types. When writing XML, the methods do extra work to produce well-formed XML. The following table provides a list of methods that do work for you to ensure that data is well-formed.

Method Description of work done

WriteAttributeString XmlTextWriter escapes the text content of the attribute depending on what it finds.

WriteString XmlTextWriter escapes special characters, replacing them with &amp; &lt; &gt; and numeric character entities when required.

WriteBase64 XmlTextWriter encodes the base64 bytes, which can then be read using ReadBinary on the XmlReader.

The following example creates XML output using the XmlTextWriter. static void WriteQuote(XmlWriter writer, string symbol,

double price, double change, long volume)

{

writer.WriteStartElement("Stock");

writer.WriteAttributeString("Symbol", symbol);

writer.WriteElementString("Price", XmlConvert.ToString(price));

writer.WriteElementString("Change", XmlConvert.ToString(change));

writer.WriteElementString("Volume", XmlConvert.ToString(volume));

writer.WriteEndElement();

}

public static void Main(){

XmlTextWriter writer = new XmlTextWriter(Console.Out);

writer.Formatting = Formatting.Indented;

WriteQuote(writer, "MSFT", 74.125, 5.89, 69020000);

writer.Close();

}

Output

Page 152: CSharp Handout v1.0

Handout - C#

Page 152 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

<Stock Symbol="MSFT">

<Price>74.125</Price>

<Change>5.89</Change>

<Volume>69020000</Volume>

</Stock>

Summary

In this session you briefly covered how to use XML in .Net Framework XmlValidatingReader: The XmlValidatingReader class is used to validate an XML file

against a document type definition (DTD) or XML-Data Reduced (XDR) schema or XML Schema definition language (XSD) validation.

XmlTextWriter: It provides a fast, non-cached, forward-only way of generating streams or files containing XML data.

XmlDocument Class: The XmlDocument class provides support for the Document Object Model (DOM) levels 1 and 2, as defined by W3C.

Test your Understanding

1. What are the namespaces used for XML in .Net framework? 2. What is the purpose of XMLTextReader? 3. What is the purpose of XMLTextWriter? 4. What are the design goals of XML?

Page 153: CSharp Handout v1.0

Handout - C#

Page 153 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 34: Delegates and Events

Learning Objectives

After completing the session, you will be able to: Work with Delegates Encapsulate a method's call from caller Call a method asynchronously Apply Multicast Delegates Create late-bound method calls using Delegates Write Custom Events

Events and Delegates:

An event is a message sent by an object to signal the occurrence of an action. The action could be caused by user interaction, such as a mouse click, or it could be triggered by some other program logic. The object that raises the event is called the event sender. The object that captures the event and responds to it is called the event receiver. In event communication, the event sender class does not know which object or method will receive (handle) the events it raises. What is needed is an intermediary (or pointer-like mechanism) between the source and the receiver. The .NET Framework defines a special type (Delegate) that provides the functionality of a function pointer. A delegate is a class that can hold a reference to a method. Unlike other classes, a delegate class has a signature, and it can hold references only to methods that match its signature. A delegate is thus equivalent to a type-safe function pointer or a callback. While delegates have other uses, the discussion here focuses on the event handling functionality of delegates. A delegate declaration is sufficient to define a delegate class. The declaration supplies the signature of the delegate, and the common language runtime provides the implementation. The following example shows an event delegate declaration. public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);

Connect Event Handler Methods to Events

To consume events defined in another class, you must define and register an event handler. The event handler must have the same method signature as the delegate declared for the event. You register your event handler by adding the handler to the event. After you have added your event handler to the event, the method is called whenever the class raises the event.

Page 154: CSharp Handout v1.0

Handout - C#

Page 154 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

1. Define an event handler method with the same signature as the event delegate.

public class WakeMeUp

{

// AlarmRang has the same signature as AlarmEventHandler.

public void AlarmRang(object sender, AlarmEventArgs e)

{...};

...

}

2. Create an instance of the delegate, using a reference to the event handler method. When

the delegate instance is called, it in turn calls the event handler method. // Create an instance of WakeMeUp.

WakeMeUp w = new WakeMeUp();

// Instantiate the event delegate.

AlarmEventHandler alhandler = new AlarmEventHandler(w.AlarmRang);

3. Add the delegate instance to the event. When the event is raised, the delegate instance

and its associated event handler method are called. // Instantiate the event source.

AlarmClock clock = new AlarmClock();

// Add the delegate instance to the event.

clock.Alarm += alhandler;

Consuming Events

To consume an event in an application, you must provide an event handler (an event-handling method) that executes program logic in response to the event and register the event handler with the event source. This process is referred to as event wiring.

The Event Pattern

A class that raises an event named EventName has the following member:

public event EventNameEventHandler EventName;

The event delegate for the EventName event is EventNameEventHandler, with the following signature:

public delegate void EventNameEventHandler(object sender, EventNameEventArgs e);

To consume the EventName event, your event handler must have the same signature as the event delegate:

void EventHandler(object sender, EventNameEventArgs e) {}

Page 155: CSharp Handout v1.0

Handout - C#

Page 155 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Raising an Event Event functionality is provided by three interrelated elements: a class that provides event data, an event delegate, and the class that raises the event. The .NET Framework has a convention for naming classes and methods related to events. If you want your class to raise an event named EventName, you need the following elements:

A class that holds event data, named EventNameEventArgs. This class must derive from System.EventArgs.

A delegate for the event, named EventNameEventHandler. A class that raises the event. This class must provide the event declaration

(EventName) and a method that raises the event (OnEventName). The event data class and the event delegate class might already be defined in the .NET Framework class library or in a third-party class library. In that case, you do not have to define those classes. For example, if your event does not use custom data, you can use System.EventArgs for your event data and System.EventHandler for your delegate. Raise and Consume Events The following example program demonstrates raising an event in one class and handling the event in another class. The AlarmClock class defines the public event Alarm, and provides methods to raise the event. The AlarmEventArgs class derives from EventArgs and defines the data specific to an Alarm event. The WakeMeUp class defines the method AlarmRang, which handles an Alarm event. The AlarmDriver class uses the classes together, setting the AlarmRang method of WakeMeUp to handle the Alarm event of the AlarmClock. This example program uses concepts described in detail in Events and Delegates and Raising an Event. // EventSample.cs.

namespace EventSample

{

using System;

using System.ComponentModel;

// Class that contains the data for the alarm event. Derives from System.EventArgs.

public class AlarmEventArgs : EventArgs

{

private readonly bool snoozePressed ;

private readonly int nrings;

public AlarmEventArgs(bool snoozePressed, int nrings)

{

this.snoozePressed = snoozePressed;

this.nrings = nrings;

}

Page 156: CSharp Handout v1.0

Handout - C#

Page 156 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

// The NumRings property returns the number of rings that the alarm clock has sounded when the alarm event is generated.

public int NumRings

{

get { return nrings;}

}

// The SnoozePressed property indicates whether the snooze button is pressed on the alarm when the alarm event is generated.

public bool SnoozePressed

{

get {return snoozePressed;}

}

// The AlarmText property that contains the wake-up message.

public string AlarmText

{

get

{

if (snoozePressed)

{

return ("Wake Up!!! Snooze time is over.");

}

else

{

return ("Wake Up!");

}

}

}

}

// Delegate declaration.

public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);

// The Alarm class that raises the alarm event.

public class AlarmClock

{

private bool snoozePressed = false;

private int nrings = 0;

private bool stop = false;

// The Stop property indicates whether the alarm should be turned off.

public bool Stop

Page 157: CSharp Handout v1.0

Handout - C#

Page 157 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

{

get {return stop;}

set {stop = value;}

}

// The SnoozePressed property indicates whether the snooze button is pressed on the alarm when the alarm event is generated.

public bool SnoozePressed

{

get {return snoozePressed;}

set {snoozePressed = value;}

}

// The event member that is of type AlarmEventHandler.

public event AlarmEventHandler Alarm;

// The protected OnAlarm method raises the event by invoking the delegates. The sender is always this, the current instance of the class.

protected virtual void OnAlarm(AlarmEventArgs e)

{

if (Alarm != null)

{

// Invokes the delegates.

Alarm(this, e);

}

}

// This alarm clock does not have a user interface. To simulate the alarm mechanism it has a loop that raises the alarm event at every iteration with a time delay of 300 milliseconds, if snooze is not pressed. If snooze is pressed, the time delay is 1000 milliseconds.

public void Start()

{

for (;;)

{

nrings++;

if (stop)

{

break;

}

else if (snoozePressed)

{

System.Threading.Thread.Sleep(1000);

{

Page 158: CSharp Handout v1.0

Handout - C#

Page 158 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

AlarmEventArgs e = new AlarmEventArgs(snoozePressed, nrings);

OnAlarm(e);

}

}

else

{

System.Threading.Thread.Sleep(300);

AlarmEventArgs e = new AlarmEventArgs(snoozePressed, nrings);

OnAlarm(e);

}

}

}

}

// The WakeMeUp class has a method AlarmRang that handles the alarm event.

public class WakeMeUp

{

public void AlarmRang(object sender, AlarmEventArgs e)

{

Console.WriteLine(e.AlarmText +"\n");

if (!(e.SnoozePressed))

{

if (e.NumRings % 10 == 0)

{

Console.WriteLine(" Let alarm ring? Enter Y");

Console.WriteLine(" Press Snooze? Enter N");

Console.WriteLine(" Stop Alarm? Enter Q");

String input = Console.ReadLine();

if (input.Equals("Y") ||input.Equals("y")) return;

else if (input.Equals("N") || input.Equals("n"))

{

((AlarmClock)sender).SnoozePressed = true;

return;

}

else

{

((AlarmClock)sender).Stop = true;

return;

}

}

}

else

Page 159: CSharp Handout v1.0

Handout - C#

Page 159 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

{

Console.WriteLine(" Let alarm ring? Enter Y");

Console.WriteLine(" Stop Alarm? Enter Q");

String input = Console.ReadLine();

if (input.Equals("Y") || input.Equals("y")) return;

else

{

((AlarmClock)sender).Stop = true;

return;

}

}

}

}

// The driver class that hooks up the event handling method of WakeMeUp to the alarm event of an Alarm object using a delegate. In a forms-based application, the driver class is the form.

public class AlarmDriver

{

public static void Main (string[] args)

{

// Instantiates the event receiver.

WakeMeUp w= new WakeMeUp();

// Instantiates the event source.

AlarmClock clock = new AlarmClock();

// Wires the AlarmRang method to the Alarm event.

clock.Alarm += new AlarmEventHandler(w.AlarmRang);

clock.Start();

}

}

}

Raising Multiple Events

If your class raises multiple events and you program these as described in Raising an Event, the compiler generates one field per event delegate instance. If the number of events is large, the storage cost of one field per delegate may not be acceptable. For those situations, the .NET Framework provides a construct called event properties (custom events in Visual Basic 2005) that you can use together with another data structure (of your choice) to store event delegates.

Page 160: CSharp Handout v1.0

Handout - C#

Page 160 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Event properties consist of event declarations accompanied by event accessors. Event accessors are methods you define to allow event delegate instances to be added or removed from the storage data structure. Note that event properties are slower than event fields, as each event delegate must be retrieved before it can be invoked. The trade-off is between memory and speed. If your class defines many events that are infrequently raised, you will want to implement event properties.

Summary

Delegates: o A delegate represents a class. o A delegate is type-safe. o You can use delegates both for static and instance methods. o You can combine multiple delegates into a single delegate. o Delegates are often used in event-based programming, such as publish or

subscribe. o You can use delegates in asynchronous-style programming. o You can define delegates inside or outside of classes.

Test your Understanding

1. What is an Event? 2. What is a Delegate? 3. What is EventWiring? 4. What is an EventHandler?

Page 161: CSharp Handout v1.0

Handout - C#

Page 161 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 37: Multithreading

Learning Objectives

After completing this session, you will be able to: Explain how threading works Differentiate between threads and processes Identify when and how to use threads

Multithreading

Multithreading is the ability of the operating system to have at the same point of time multiple threads in memory which switch between the tasks so as to provide a pseudo parallelism, as if all the tasks are running simultaneously. This illusion of concurrency is ensured by the Operating System by providing a specific time slice to each and every thread and then switching between the threads once their slice is over. This switching is very fast. The switching between the threads involves a context switch which in turn involves saving the current thread’s state, flushing the CPU and handling control of the CPU to the next thread in the queue. Remember that at any point of time the CPU can execute only one thread. It is to be noted here that Multiprocessing involves multiple processor with each executing one thread at any particular point of time. Multithreading can be of the following two types:

Cooperative Preemptive

In the Cooperative mode of multithreading a thread can have the control of the processor as long as it needs without the need to necessarily preempt them. In order words, in this type of multithreading the control of the processor lies with the executing thread. In the preemptive mode of operation however, the operating system has control over the processor and decides the time slice for each thread for which it would execute and preempts threads if and when required.

Thread States:

From the Operating System concepts we can classify a thread broadly in one of the following states.

Ready or Runnable state Running state Wait state

When a thread is first created it is put in the ready state. A thread in the ready state is one that has all the required resources for it to execute except the processor. It waits in the runnable queue for its turn to come. It would be scheduled from the ready or the runnable state to the running state when its turn comes. However, a thread of a higher priority than another thread would be scheduled prior to the other threads in the ready queue. A thread in the wait state is waiting for its IO to be complete.

Page 162: CSharp Handout v1.0

Handout - C#

Page 162 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

A thread is scheduled from the runnable queue to the running state by a module of the operating system known as the scheduler. A thread in the running state has everything including the processor. Remember that at any point of time a single processor can execute only one thread.

How Threading Works:

Multithreading is managed internally by a thread scheduler, a function the CLR typically delegates to the operating system. A thread scheduler ensures all active threads are allocated appropriate execution time, and that threads that are waiting or blocked – for instance – on an exclusive lock, or on user input – do not consume CPU time. On a single-processor computer, a thread scheduler performs time-slicing – rapidly switching execution between each of the active threads. On a multi-processor computer, multithreading is implemented with a mixture of time-slicing and genuine concurrency – where different threads run code simultaneously on different CPUs. It's almost certain there will still be some time-slicing, because of the operating system's need to service its own threads – as well as those of other applications. A thread is said to be preempted when its execution is interrupted due to an external factor such as time-slicing.

The Thread Pool class

Thread Pooling is a concept where the tasks are stored in a queue and the threads are created to handle these tasks. This creation of the threads is taken care of by the Thread Pool itself. Thus thread management is handled by the thread pool. Thread Pooling is enabled by the usage of the Thread Pool class in the System. Threading namespace. It enables us to use the resources efficiently by optimizing thread time slices on the processor. At any point of time there would be one thread pool per process and the maximum limit is 25 indicating that the thread pool can contain, at any point of time, a maximum of 25 worker threads in the pool. The Thread Pool creates the worker threads and assigns each a task from among the pending tasks in the queue.

Multithreading in C#

The C# library has a namespace called System. Threading that provides the functionality of implementing threads in C supported thread states in C#. In Sun’s Java and Microsoft’s .NET we find that they have modified or enhanced the above states and given some meaningful names to them. The Thread State enum in the System.Threading namespace in C# contains the various supported thread states in .NET. The following are the members of the ThreadState enum.

Unstarted Running Background StopRequested Suspended

Page 163: CSharp Handout v1.0

Handout - C#

Page 163 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

SuspendRequested WaitSleepJoin Aborted AbortRequested Stopped

Thread Priorities: Based on their importance we can set the priorities of threads. Meaning we can set a thread as having a higher priority than another. Here is an example: suppose there is an application where the application is accepting user input using a thread and another thread is displaying a message to the user indicating the time that has elapsed after the form has be opened. We can set the thread that is responsible for accepting the user input to a higher priority than the other to increase the user responsiveness. This is because the thread with the higher priority would be executed more frequently than one that has a lower priority. Thread priorities in C# are defined using the ThreadPriority enum. The following are the possible values:

Highest AboveNormal Normal BelowNormal Normal

Creating threads in C#: The Thread class that belongs to the System.Threading namespace contains the necessary members for creating, suspending, resuming and aborting threads. Let’s take an example. Consider the following code. using System;

using System.Text;

using System.Threading;

namespace thread

{

class ThreadTest

{

static void Main()

{

Thread t = new Thread (new ThreadStart (Go));

t.Start(); // Run Go() on the new thread.

Go(); // Simultaneously run Go() in the main thread.

}

static void Go()

{

Console.WriteLine ("hello!");

Page 164: CSharp Handout v1.0

Handout - C#

Page 164 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

}

}

}

When the thread object is first created it is in the unstarted state. The Start () method is responsible for starting the thread. Remember that when we start a thread it might not be immediately started. To be specific, it is actually put in the ready or the runnable state. It is the responsibility of the Operating System to actually schedule the thread from the runnable state to the running state.

Advantages and Disadvantages of Multithreading

The following are the major advantages of using Multithreading: Improved responsiveness Faster execution Better CPU and Memory utilization Support for Concurrency

The following are the drawbacks of using threads:

Problems in testing and debugging due to the non – deterministic nature of execution Complexity

Summary

A thread is an independent execution path, which is able to run simultaneously with other threads.

Multithreading is managed internally by a thread scheduler, a function the CLR typically delegates to the operating system.

The key difference between threads and processes: o Processes are fully isolated from each other. o Threads share memory with other threads running in the same application.

To achieve the thread safety, you need to synchronize the threads accessing the shared memory.

A deadlock is a bug when two threads are trying to access resources, which are locked by each other.

Using threads, you can obtain concurrency, Synchronize memory, and Schedule resources.

Page 165: CSharp Handout v1.0

Handout - C#

Page 165 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Test Your Understanding

1. What is multithreading? 2. What are the different states of thread? 3. How do threading works? 4. What is a Thread Pool class? 5. What is multithreading in C#? 6. What are the possible priority values in Thread priority?? 7. State the advantage of multithreading. 8. State the disadvantage of Multithreading.

Page 166: CSharp Handout v1.0

Handout - C#

Page 166 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 40: Reflection and Serialization

Learning Objectives

After completing this session, you will be able to: Acquire Class and Type Information Acquire Member Information from a Class Invoke dynamically methods from Classes

Reflection

You saw that a .NET application contains code, data, and metadata. Metadata is information about the data—that is, information about the types, code, assembly, and so forth—that is stored along with your program. Attributes are a mechanism for adding metadata, such as compiler instructions and other data about your data, methods, and classes, to the program itself. Attributes are inserted into the metadata and are visible through ILDasm and other metadata-reading tools. An attribute is an object that represents data you want to associate with an element in your program. The element to which you attach an attribute is referred to as the target of that attribute. For example, the attribute: [assembly: AssemblyKeyFile("c:\myStrongName.key")]

Inserts metadata into the assembly to designate the program's StrongName. Reflection is the process by which a program can read a .NET assemblies metadata. The classes in the System.Reflection namespace, along with the System.Type and System.TypedReference classes, provide support for examining and interacting with the metadata. Reflection is generally used for any of following tasks:

Viewing metadata This might be used by tools and utilities that wish to display metadata. Performing type discovery This allows you to examine the types in an assembly and interact with or instantiate

those types. This can be useful in creating custom scripts. For example, you might want to allow your users to interact with your program using a script language, such as JavaScript, or a scripting language you create yourself.

Late binding to methods and properties This allows the programmer to invoke properties and methods on objects dynamically

instantiated based on type discovery. This is also known as dynamic invocation. Creating types at runtime (Reflection Emit)

Page 167: CSharp Handout v1.0

Handout - C#

Page 167 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

The ultimate use of reflection is to create new types at runtime and then to use those types to perform tasks. You might do this when a custom class, created at runtime, will run significantly faster than more generic code created at compile time. Viewing metadata You will use the C# Reflection support to read the metadata for a class. We start by initializing an object of the type MemberInfo. This object, in the System.Reflection namespace, is provided to discover the attributes of a member and to provide access to the metadata: System.Reflection.MemberInfo inf = typeof(MyMathClass);

object[] attributes;

attributes =

inf.GetCustomAttributes(typeof(AnyAttribute),false);

foreach(Object attribute in attributes)

{

// read the attribute values

}

Performing type discovery You can use reflection to explore and examine the contents of an assembly. You can find the types associated with a module; the methods, fields, properties, and events associated with a type, as well as the signatures of each of the type's methods; the interfaces supported by the type; and the type's base class. // what is in the assembly

Assembly a = Assembly.Load("Mscorlib.dll");

Type[] types = a.GetTypes( );

foreach(Type t in types)

{

MessageBox.Show("Type is {0}" + t.ToString());

}

Late binding to methods and properties You can reflect on a single type in the mscorlib assembly as well. To do so, you extract a type from the assembly with the GetType( ) method: //examine a single object

Type theType = Type.GetType("System.Reflection.Assembly");

MessageBox.Show("Single Type is " + theType.ToString());

Also you can query the Assembly type for all its members using the GetMembers( ) method of the Type class, which lists all the methods, properties, and fields. Once you have discovered a method, it's possible to invoke it using reflection. You could, of course, call the method in the normal course of your code, but reflection allows you to bind to that method at runtime. This is called latebinding and offers the flexibility of choosing at runtime which object you will bind to and invoking it programmatically.

Page 168: CSharp Handout v1.0

Handout - C#

Page 168 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Creating types at runtime One of the powerful use of reflection, however, is with reflection emit. Reflection emit supports the dynamic creation of new types at runtime. In the following sample a type is created on the fly; compiled and finally the type is loaded to memory. // generate the code and compile it

private void GenerateCode(ref Type theType, ref object theClass)

{

// open the file for writing

string fileName = "EmitClass";

Stream s =

File.Open(fileName + ".cs", FileMode.Create);

StreamWriter wrtr = new StreamWriter(s);

wrtr.WriteLine(

"// Dynamically created class");

// create the class

string className = "EmitClass";

wrtr.WriteLine("class {0}", className);

wrtr.WriteLine("{");

// create the method

wrtr.WriteLine("\tpublic string Hello( )");

wrtr.WriteLine("\t{");

// write the brute force additions

wrtr.Write("\treturn \"Hello Reflection\"");

wrtr.WriteLine(";"); // finish method

wrtr.WriteLine("\t}"); // end method

wrtr.WriteLine("}"); // end class

// close the writer and the stream

wrtr.Close( );

s.Close( );

// Build the file

ProcessStartInfo psi =

new ProcessStartInfo( );

psi.FileName = "cmd.exe";

string compileString = "/c csc /optimize+ ";

compileString += "/target:library ";

compileString += "{0}.cs > compile.out";

psi.Arguments =

String.Format(compileString, fileName);

psi.WindowStyle = ProcessWindowStyle.Minimized;

Process proc = Process.Start(psi);

proc.WaitForExit( ); // wait at most 2 seconds

// Open the file, and get a

Page 169: CSharp Handout v1.0

Handout - C#

Page 169 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

// pointer to the method info

Assembly a =

Assembly.LoadFrom(fileName + ".dll");

theClass = a.CreateInstance(className);

theType = a.GetType(className);

}

//reflect the type and invoke the method

GenerateCode(theType, theClass);

// with the reference to the dynamically

// created class you can invoke the method

object[] arguments = new object[0];

object retVal =

theType.InvokeMember("Hello", BindingFlags.Default | BindingFlags.InvokeMethod, null, theClass, arguments);

Summary

Reflection is the mechanism of discovering class information solely at run time. Using Reflection, you can obtain class and type information, member information.

Test Your Understanding

1. What are the uses of Reflection? 2. What is Reflection?

Page 170: CSharp Handout v1.0

Handout - C#

Page 170 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 42: Reflection and Serialization

Learning Objectives

After completing this session, you will able to: Describe overview of Serialization Identify the types of Serialization

Overview

Serialization is a process of converting an object into a stream of data so that it can be is easily transmittable over the network or can be continued in a persistent storage location. This storage location can be a physical file, database or ASP.NET Cache. Serialization is the technology that enables an object to be converted into a linear stream of data that can be easily passed across process boundaries and machines. This stream of data needs to be in a format that can be understood by both ends of a communication channel so that the object can be serialized and reconstructed easily. Serialization is used by Remoting, Web Services SOAP for transmitting data between a server and a client. The Remoting technology of .NET makes use of serialization to pass objects by value from one application domain to another.

What is Serialization and De-serialization?

Serialization is the process of saving the state of an object in a persistent storage media by converting the object to a linear stream of bytes. The object can be persisted to a file, a database or even in the memory. The reverse process of serialization is known as de-serialization and enables us to re-construct the object from the previously serialized instance of the same in the persistent or non-persistent storage media. Serialization in .NET is provided by the System.Runtime.Serialization namespace. This namespace contains an interface called IFormatter which in turn contains the methods Serialize and De-serialize that can be used to save and load data to and from a stream. In order to implement serialization in .NET, you basically require a stream and a formatter. While the stream acts as a container for the serialized objects, the formatter is used to serialize these objects onto the stream. The basic advantage of serialization is the ability of an object to be serialized into a persistent or a non-persistent storage media and then reconstructing the same object if required at a later point of time by de-serializing the object. Remoting and Web Services depend heavily on Serialization and De-serialization.

Page 171: CSharp Handout v1.0

Handout - C#

Page 171 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Types of Serialization Serialization can be of the following types:

Binary Serialization SOAP Serialization XML Serialization Custom Serialization

Binary Serialization: Binary serialization is a mechanism which writes the data to the output stream such that it can be used to re-construct the object automatically. The term binary in its name implies that the necessary information that is required to create an exact binary copy of the object is saved onto the storage media. public void BinarySerialize(string filename, Employee emp)

{

FileStream fileStreamObject;

try

{

fileStreamObject = new FileStream(filename, FileMode.Create);

BinaryFormatter binaryFormatter = new BinaryFormatter();

binaryFormatter.Serialize(fileStreamObject, emp);

}

finally

{

fileStreamObject.Close();

}

}

Page 172: CSharp Handout v1.0

Handout - C#

Page 172 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Advantages and Disadvantages of Binary Serialization: The following are the major advantages of using Binary Serialization:

The object can be de-serialized from the same data you serialized it to. Enhanced performance as it is faster and even more powerful Provides support for complex objects, read only properties and even circular

references. The following is the drawback of using Binary Serialization

Not easily portable to another platform. Soap Serialization: The SOAP protocol is ideal for communicating between applications that use heterogeneous architectures. In order to use SOAP serialization in .NET we have to add a reference to System.Runtime.Serialization.Formatters.Soap in the application. The basic advantage of SOAP serialization is portability. The SoapFormatter serializes objects into SOAP messages or parses SOAP messages and extracts serialized objects from the message. public void SOAPSerialize(string filename,Employee employeeObject)

{

FileStream fileStreamObject = new FileStream(filename, FileMode.Create);

SoapFormatter soapFormatter = new SoapFormatter();

soapFormatter.Serialize(fileStreamObject, employeeObject);

fileStreamObject.Close();

}

XML Serialization: "XML serialization converts (serializes) the public fields and properties of an object or the parameters and returns values of methods, into an XML stream that conforms to a specific XML Schema definition language (XSD) document. XML serialization results in strongly typed classes with public properties and fields that are converted to a serial format (in this case, XML) for storage or transport. Because XML is an open standard, the XML stream can be processed by any application, as needed, regardless of platform." Implementing XML Serialization in .Net is quite simple. The basic class that we need to use is the XmlSerializer for both serialization and de-serialization. The Web Services use the SOAP protocol for communication and the return types and the parameters are all serialized using the XmlSerializer class. XML Serialization is however, much slower compared to Binary serialization. public void XMLSerialize(Employee emp, String filename)

{

XmlSerializer serializer = null;

FileStream stream = null;

try

{

serializer = new XmlSerializer(typeof(Employee));

stream = new FileStream(filename, FileMode.Create, FileAccess.Write);

serializer.Serialize(stream, emp);

}

finally

Page 173: CSharp Handout v1.0

Handout - C#

Page 173 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

{

if (stream != null)

stream.Close();

}

}

The advantages of XML Serialization are as follows:

XML based Support for cross platforms Easily readable and editable

Custom Serialization: In some cases, the default serialization techniques provided by .NET may not be sufficient in real life. This is when we require implementing custom serialization. It is possible to implement custom serialization in .NET by implementing the ISerializable interface. This interface allows an object to take control of its own serialization and de-serialization process. It gives us a great deal of flexibility in the way we can save and restore objects. public class Employee: ISerializable

{

private int empCode;

private string empName;

protected Employee(SerializationInfo serializationInfo, StreamingContext

streamingContext)

{

this.empCode = serializationInfo.GetInt32("empCode");

this.empName = serializationInfo.GetString("empName");

}

public void ISerializable.GetObjectData(SerializationInfo serializationInfo,

StreamingContext streamingContext)

{

serializationInfo.AddValue("empCode", this.empCode);

serializationInfo.AddValue("empName", this.empName);

}

}

Working with formatters:

A formatter is used to determine the serialization format for objects. In other words, it is used to control the serialization of an object to and from a stream. They are the objects that are used to encode and serialize data into an appropriate format before they are transmitted over the network. They expose an interface called the IFormatter interface. IFormatter's significant methods are Serialize and De-serialize which perform the actual serialization and de-serialization.There are two formatter classes provided within .NET, the BinaryFormatter and the SoapFormatter. Both these classes extend the IFormatter interface.

Page 174: CSharp Handout v1.0

Handout - C#

Page 174 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

The Binary Formatter: The Binary formatter provides support for serialization using binary encoding. The BinaryFormater class is responsible for binary serialization and is used commonly in .NET's Remoting technology. This class is not appropriate when the data is supposed to be transmitted through a firewall. The SOAP Formatter: The SOAP formatter provides formatting that can be used to serialize objects using the SOAP protocol. It is used to create a Soap envelop and it uses an object graph to generate the result. It is responsible for serializing objects into SOAP messages or parsing the SOAP messages and extracting these serialized objects from the SOAP messages. SOAP formatters in .NET are widely used by the Web Services.

Advantages and disadvantages of serialization

The following are the basic advantages of serialization: Facilitate the transportation of an object through a network Create a clone of an object

The primary disadvantages of serialization are:

Resource overhead (both the CPU and the IO devices) Latency issues that are involved for transmitting the data over the network Serialization is quite slow. XML serialization is insecure, consumes a lot of space on the disk and it works on

public members and public classes and not on the private or internal classes.

Summary

.NET provides built-in object serialization services. Serialization will moves from field-level to object-level. You can generalize serialization to allow XML, SOAP, Binary formats and other future

formats. Various types of Serialization are Binary Serialization, SOAP Serialization, XML

Serialization, and Custom Serialization.

Test Your Understanding

1. What is Serialization? 2. What is Deserialization? 3. What are the Types of serialization? 4. What is a Binary Serialization? 5. What are the advantages and disadvantages of using Binary Serialization? 6. What is Soap Serialization? 7. What is XML Serialization? 8. What is Custom Serialization? 9. What is Binary Formatter? 10. What is Soap Formatter? 11. What are the advantages and disadvantages of Serialization?

Page 175: CSharp Handout v1.0

Handout - C#

Page 175 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 45: .NET Interoperability

Learning Objectives

After completing this session, you will be able to: Work with Unmanaged Code Describe the Interoperability through Runtime wrappers Explain programming model comparison of .NET-COM interoperability Describe .NET Marshalling

Overview of .NET and COM interoperability

The .NET framework is a natural progression from COM because the two models share many central themes, including component reuse and language neutrality. For backward compatibility, COM interop provides access to existing COM components without requiring that the original component be modified. We can incorporate COM components into a .NET Framework application by using COM interop tools to import the relevant COM types. Once imported, the COM types are ready to use. COM interop also introduces forward compatibility by enabling your COM clients to access managed code as easily as they access other COM objects. Again, COM interop provides the means to seamlessly export metadata in an assembly to a type library and registers the managed component as a traditional COM component. Both the import and export utilities produce results consistent with COM specifications. At run time, the common language runtime marshals data between COM objects and managed objects as needed.

Interoperability through Runtime wrappers

The common language runtime exposes COM objects through a proxy called the runtime callable wrapper (RCW). Although the RCW appears to be an ordinary object to .NET clients, its primary function is to marshal calls between a .NET client and a COM object. The runtime creates exactly one RCW for each COM object, regardless of the number of references that exist on that object. As the following illustration shows, any number of managed clients can hold a reference to the COM objects that expose INew and INewer interfaces. The runtime maintains a single RCW for each object.

Page 176: CSharp Handout v1.0

Handout - C#

Page 176 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Accessing COM objects through the runtime callable wrapper

Using metadata derived from a type library, the runtime creates both the COM object being called and a wrapper for that object. Each RCW maintains a cache of interface pointers on the COM object it wraps and releases its reference on the COM object when the RCW is no longer needed. The runtime performs garbage collection on the RCW. Among other activities, the RCW marshals data between managed and unmanaged code, on behalf of the wrapped object. Specifically, the RCW provides marshaling for method arguments and method return values whenever the client and server have different representations of the data passed between them. The standard wrapper enforces built-in marshaling rules. For example, when a .NET client passes a String type as part of an argument to an unmanaged object, the wrapper converts the string to a BSTR type. Should the COM object return a BSTR to its managed caller, the caller receives a String. Both the client and the server send and receive data that is familiar to them. Other types require no conversion. For instance, a standard wrapper will always pass a 4-byte integer between managed and unmanaged code without converting the type.

Programming Model comparison of .NET-COM interoperability

The following table compares the .NET and COM based component programming models. .NET COM

Object based communication Interface based communication

Garbage Collector to manage memory Reference count will be used to manage memory

Type Standard objects Binary Standard objects

Objects are created by normal new operator

Objects are created by coCreateInstance

Exceptions will be returned HRESULT will be returned

Object info resides in assembly files Object info resides in Type library

Before the application starts to communicate, there are some technical constraints associated with this. When an object is transmitted to a receiver which is in a separate machine/process (managed/unmanaged) space, the object may need to undergo a transformation according to the native type to make it suitable for use by the recipient. That is the object will be converted into a recipient readable form. This process of converting an object between types when sending it across contexts is known as marshaling.

Page 177: CSharp Handout v1.0

Handout - C#

Page 177 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

.NET Marshalling

.NET runtime automatically generates code to translate calls between managed code and unmanaged code. While transferring calls between these two codes, .NET handles the data type conversion also. This technique of automatically binding with the server data type to the client data type is known as marshalling. Marshaling occurs between managed heap and unmanaged heap. For example, Fig.4 shows a call from the .NET client to a COM component. This sample call passes a .NET string from the client. The RCW converts this .NET data type into the COM compatible data type. In this case COM compatible data type is BSTR. Thus the RCW converts the .NET string into COM compatible BSTR. This BSTR will be passed to the object and the required calls will be made. The results will be returned to back to the RCW. The RCW converts this COM compatible result to .NET native data type.

Fig.4 Sample diagram for marshalling

Logically the marshalling can be classified into 2 types.

Interop marshalling COM marshalling

If a call occurs between managed code and unmanaged code with in the same apartment, Interop marshaler will play the role. It marshals data between managed code and unmanaged code. In some scenarios COM component may be running in different apartment threads. In those cases that is, calling between managed code and unmanaged code in different apartments or process, both Interop marshaler and COM marshaler are involved.

Interop marshaler

When the server object is created in the same apartment of client, all data marshaling is handled by Interop marshaling.

Page 178: CSharp Handout v1.0

Handout - C#

Page 178 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

COM Marshaler

COM marshaling involved whenever the calls between managed code and unmanaged code are in different apartments. For example, when a .NET client (with the default apartment settings) communicates with a COM component (whichever developed in VB6.0), the communication occurs through proxy and stub because both the objects will be running in different apartment threads. (The default apartment settings of .NET objects are STA and the components which are developed by VB6.0 are STA). Between these two different apartments COM marshaling will occurs and within the apartment Interop marshaling will occurs. Fig.6 shows this kind of marshaling. This kind of different apartment communication will impact the performance. The apartment settings of the managed client can be changed by changing the STAThreadAttribute / MTAThreadAttribute / Thread.ApartmentState property. Both the codes can run in a same apartment, by making the managed code’s thread to STA. (If the COM component is set as MTA, then cross marshaling will occurs.)

In the earlier scenario, the call with in different apartments will occur by COM marshaling and the call between managed and unmanaged code will occur by Interop marshaling.

Summary

Com interoperability: COM interop provides the means to seamlessly export metadata in an assembly to a type library and registers the managed component as a traditional COM component.

Interoperability through Runtime wrappers: The common language runtime exposes COM objects through a proxy called the runtime callable wrapper (RCW). Although the RCW appears to be an ordinary object to .NET clients, its primary function is to marshal calls between a .NET client and a COM object.

.NET Marshalling: Automatically binding with the server data type to the client data type is known as marshalling. Marshaling occurs between managed heap and unmanaged heap.

Marshalling can be classified into 2 types: o Interop marshalling o COM marshalling

When the server object is created in the same apartment of client, all data marshaling is handled by Interop marshaling.

COM marshaling involved whenever the calls between managed code and unmanaged code are in different apartments

Page 179: CSharp Handout v1.0

Handout - C#

Page 179 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Test your Understanding

1. What is interoperability? 2. What is unmanaged code with examples? 3. Differentiate between managed code and unmanaged code? 4. What is RCW? 5. Differentiate between RCW and CCW? 6. What is marshalling? 7. What are the types of marshalling?

Page 180: CSharp Handout v1.0

Handout - C#

Page 180 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 47: Remoting

Learning Objectives

After completing this session, you will be able to: Explain the .NET Remoting Basics and Concepts Describe the .NET Remoting Architecture

.NET Remoting basics

.NET remoting enables you to build widely distributed applications easily, whether the application components are all on one computer or spread out across the entire world. You can build client applications that use objects in other processes on the same computer or on any other computer that is reachable over its network. You can also use .NET remoting to communicate with other application domains in the same process. .NET remoting provides an abstract approach to interprocess communication that separates the remotable object from a specific client or server application domain and from a specific mechanism of communication. As a result, it is flexible and easily customizable. You can replace one communication protocol with another or one serialization format with another without recompiling the client or the server. In addition, the remoting system assumes no particular application model. You can communicate from a Web application, a console application, a Windows Service – from almost anything you want to use. Remoting servers can also be any type of application domain. Any application can host remoting objects and provide its services to any client on its computer or network. To use .NET remoting to build an application in which two components communicate directly across an application domain boundary, you need to build only the following:

A remotable object. A host application domain to listen for requests for that object. A client application domain that makes requests for that object.

.NET Remoting concepts

Building an application that uses .NET Framework remoting to communicate across application domain boundaries is very straightforward. You must have an implementation of a remotable type, a listening or host application domain, a client or calling application domain, and you must configure the remoting system in each application domain to use remote activation for the remotable type. This process applies no matter how complex your remoting scenario becomes.

Page 181: CSharp Handout v1.0

Handout - C#

Page 181 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Building a Remotable Type:

To enable objects in other application domains to use an instance of your class, your class must inherit from MarshalByRefObject. The following procedure describes how to create a simple object that can be created and invoked from objects executing in another application domain.

1. Define a class that derives from the MarshalByRefObject class public class CustomRemotableException : RemotingException, ISerializable {

……….}

2. Implement the methods and properties for that class as you would for a non-remotable

type. private string StringValue = "This is the RemotableType.";

public string StringMethod(){

return StringVale;

}

3. Save the class as Filename.language-extension (or use another file name of your choice,

where the language extension is the language you want to compile), and at the command prompt in the directory in which you saved the file, type the following command: csc /noconfig /t:library RemotableType.cs

Building a Host Application:

Using a configuration file enables you to change the remoting configuration without recompiling your executable, among other things. For details on the configuration of the .NET remoting infrastructure:

1. Create a configuration file for the remote class. The host application must be able to find the configuration file to load the configuration for the remote class, and therefore, the configuration file should be saved in the same directory as the host application, or it will not be found and an exception will be thrown. The following code shows the Listener.exe.config configuration file for a host application domain. <configuration>

<system.runtime.remoting>

<application>

<service>

<wellknown

mode="Singleton"

type="RemotableType, RemotableType"

objectUri="RemotableType.rem"

/>

</service>

<channels>

<channel ref="http" port="8989"/>

</channels>

Page 182: CSharp Handout v1.0

Handout - C#

Page 182 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

</application>

</system.runtime.remoting>

</configuration>

2. Import the System.Runtime.Remoting namespace

using System;

using System.Runtime.Remoting;

Load the configuration file that configures the remote class.

public class Listener{

public static void Main(){

RemotingConfiguration.Configure("Listener.exe.config");

}

}

3. Compile this class into a host or listener executable using the command-line tools that ship

with the .NET Framework SDK, save it as Listener.language-extension (or use another file name of your choice, where the language extension is the language you want to compile). Save the file in the same directory in which you saved the RemotableType. At the command prompt in that directory, type the following command: csc /noconfig /r:RemotableType.dll Listener.cs

Build a Client Application:

Application must register itself as a client for that remote object, and then invoke it as though it were within the client's application domain. The .NET remoting system will intercept your client calls, forward them to the remote object, and return the results to your client. The following code procedure describes how to build a simple remoting client.

1. Import the System.Runtime.Remoting namespace 2. Create a client configuration file so that the client application can locate the remote object,

and save the file in the same folder as the client application. For example the following configuration file tells the remoting system that the type information for the RemotableType remote object can be found in the RemotableType assembly, and that the client should attempt to create and use a RemotableType object located at http://localhost:8989/RemotableType.rem. <configuration>

<system.runtime.remoting>

<application>

<client>

<wellknown

type="RemotableType, RemotableType"

url="http://localhost:8989/RemotableType.rem"

/>

</client>

</application>

</system.runtime.remoting>

</configuration>

Page 183: CSharp Handout v1.0

Handout - C#

Page 183 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

3. Save the client application as Client.language-extension. Save the file in the same directory in which you saved a copy of the RemotableType.

4. Compile client application or calling executable using the command-line tools that ship with the .NET Framework SDK. For example, to compile the client application Client.language-extension, at the command prompt change directory to the folder where the client application has been saved and type the following command: csc /noconfig /r:RemotableType.dll Client.cs

.NET Remoting Architecture

Using object references to communicate between server objects and clients is the heart of remoting. The remoting architecture, however, provides the programmer with an even simpler procedure. If we configure the client properly, we need only create a new instance of the remote object using new (or the instance creation function from your managed programming language). Your client receives a reference to the server object, and you can then call its methods as though the object were in your process rather than running on a separate computer. The remoting system uses proxy objects to create the impression that the server object is in the client's process. Proxies are stand-in objects that present themselves as some other object. When your client creates an instance of the remote type, the remoting infrastructure creates a proxy object that looks exactly like the remote type to your client. Client calls a method on that proxy, and the remoting system receives the call, routes it to the server process, invokes the server object, and returns the return value to the client proxy, which returns the result to the client. Remote calls must be conveyed in some way between the client and the server process. If you were building a remoting system yourself, you might start by learning network programming and a wide array of protocols and serialization format specifications. In the .NET remoting system, the combination of underlying technologies required to open a network connection and use a particular protocol to send the bytes to the receiving application are represented as a transport channel. A channel is a type that takes a stream of data, creates a package according to a particular network protocol, and sends the package to another computer. Some channels can only receive information, others can only send information, and still others, such as the default TcpChannel and HttpChannel classes, can be used in either direction.

Page 184: CSharp Handout v1.0

Handout - C#

Page 184 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Suppose you have an application running on one computer, and you want to use the functionality exposed by a type that is stored on another computer. The following illustration shows the general remoting process.

If both sides of the relationship are configured properly, a client merely creates a new instance of the server class. The remoting system creates a proxy object that represents the class and returns to the client object a reference to the proxy. When a client calls a method, the remoting infrastructure handles the call, checks the type information, and sends the call over the channel to the server process. A listening channel picks up the request and forwards it to the server remoting system, which locates (or creates, if necessary) and calls the requested object. The process is then reversed, as the server remoting system bundles the response into a message that the server channel sends to the client channel. Finally, the client remoting system returns the result of the call to the client object through the proxy. Very little actual code is required to make this work, but some thought should be given to the design and the configuration of the relationship. The code can be absolutely correct and yet fail because a URL or port number is incorrect.

Summary

.NET remoting is an enabler for application communication. In .NET when an application is loaded in memory a process is created and within

process an application domain is created. The Channels connects the server application domain and the client application

domain. The proxy looks and feels like the real object, however it merely holds a reference to

the remotable object.

Page 185: CSharp Handout v1.0

Handout - C#

Page 185 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Test your Understanding

1. What is Remoting? 2. What is the advantage of using remoting? 3. What is Application Domain? 4. Describe channels and proxy? 5. What are the basic rules which are applicable for Remoting? 6. What are the object modes for server activation?

Page 186: CSharp Handout v1.0

Handout - C#

Page 186 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 48: Remoting

Learning Objectives

After completing this session, you will be able to: Develop .NET Remoting service Develop and configure Remoting Server and Client

Remoting Application:

.NET remoting enables you to build widely distributed applications easily, whether the application components are all on one computer or spread out across the entire world. You can build client applications that use objects in other processes on the same computer or on any other computer that is reachable over its network. You can also use .NET remoting to communicate with other application domains in the same process. .NET remoting provides an abstract approach to interprocess communication that separates the remotable object from a specific client or server application domain and from a specific mechanism of communication. As a result, it is flexible and easily customizable. You can replace one communication protocol with another or one serialization format with another without recompiling the client or the server. In addition, the remoting system assumes no particular application model. You can communicate from a Web application, a console application, a Windows Service – from almost anything you want to use. Remoting servers can also be any type of application domain. Any application can host remoting objects and provide its services to any client on its computer or network. To use .NET remoting to build an application in which two components communicate directly across an application domain boundary, you need to build only the following:

A remotable object. A host application domain to listen for requests for that object. A client application domain that makes requests for that object.

Build a Remotable Type

To enable objects in other application domains to use an instance of your class, your class must inherit from MarshalByRefObject. using System;

public class RemotableType : MarshalByRefObject

{

private string StringValue = "This is the RemotableType.";

public string StringMethod()

{

return StringValue;

}

}

Page 187: CSharp Handout v1.0

Handout - C#

Page 187 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Host Application

By itself, the RemotableType class defined in the How To: Build a Remotable Type topic is not special. To enable objects in other application domains to create instances of this object remotely, you must build a host or listener application to do two things:

Choose and register a channel, which is an object that handles the networking protocols and serialization formats on your behalf.

Register your type with the .NET remoting system so that it can use your channel to listen for requests for your type.

The .NET Framework includes two default channels, HttpChannel (which uses SOAP formatting) and TcpChannel (which uses binary formatting). HttpChannel is a good channel to start with because in some scenarios, it can be used through firewalls without opening a port, and it supports standard security and authentication protocols. For more information about choosing channels that suit your scenario. Refer Channels. You can build listener applications using any type of application domain — a Windows Forms application, an ASP.NET Web application, a console application, a Windows Service (also known as a Windows NT Service), or any other managed application domain. Because remote configuration is done on a per-application-domain basis, the application domain must be running to listen for requests. Configuration can be done programmatically or by using an application or machine configuration file. The remoting system uses the information in this file to listen for and route remote requests to an instance of a remotable type.

Build a Hosting Application

Create a configuration file for the remote class. The host application must be able to find the configuration file to load the configuration for the remote class, and therefore, the configuration file should be saved in the same directory as the host application, or it will not be found and an exception will be thrown. The following code shows the Listener.exe.config configuration file for a host application domain. <configuration>

<system.runtime.remoting>

<application>

<service>

<wellknown mode="Singleton" type="RemotableType, RemotableType"

objectUri="RemotableType.rem" />

</service>

<channels>

<channel ref="http" port="8989"/>

</channels>

</application>

</system.runtime.remoting>

</configuration>

Page 188: CSharp Handout v1.0

Handout - C#

Page 188 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Load the configuration file that configures the remote class: // Listener.cs

using System;

using System.Runtime.Remoting;

public class Listener{

public static void Main(){

RemotingConfiguration.Configure("Listener.exe.config");

Console.WriteLine("Listening for requests. Press Enter to exit...");

Console.ReadLine();

}

}

Build a Client Application

To build a client of the remote type, your application must register itself as a client for that remote object, and then invoke it as though it were within the client's application domain. The .NET remoting system will intercept your client calls, forward them to the remote object, and return the results to your client. The following code procedure describes how to build a simple remoting client. Create a client configuration file so that the client application can locate the remote object, and save the file in the same folder as the client application. For example the following configuration file tells the remoting system that the type information for the RemotableType remote object can be found in the RemotableType assembly, and that the client should attempt to create and use a RemotableType object located at http://localhost:8989/RemotableType.rem. <configuration>

<system.runtime.remoting>

<application>

<client>

<wellknown type="RemotableType, RemotableType"

url="http://localhost:8989/RemotableType.rem" />

</client>

</application>

</system.runtime.remoting>

</configuration>

// Client.cs

using System;

using System.Runtime.Remoting;

public class Client

{

public static void Main()

Page 189: CSharp Handout v1.0

Handout - C#

Page 189 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

{

RemotingConfiguration.Configure("Client.exe.config");

RemotableType remoteObject = new RemotableType();

Console.WriteLine(remoteObject.StringMethod());

}

}

Remoting Task List

.NET remoting is one of several ways to establish communication between application domains using the .NET Framework. You must decide which features your application requires and consider the resources you have at your disposal before choosing a particular development model for your distributed application. For guidance, see Choosing Communication Options in .NET . The following task lists describe the fundamental steps required to build a basic .NET remoting application.

Host Tasks

The following steps are required to publish any service for use from outside your application domain:

1. Design your service. a. Choose a host application domain. b. Choose an activation model. c. Choose a channel and port. d. Decide how the client will obtain your service's metadata.

2. Implement your host application domain. Remoting hosts might be Windows Services, console applications, Windows Forms applications, Internet Information Services (IIS) processes, or ASP.NET applications. Requirements for each type of application vary, so you should read the documentation describing how to build the type of application you want to use. For more information, see Windows-based Applications or ASP.NET Web Applications. In the host, configure the remoting system for activation mode and other information, such as application name and endpoint. If you want to programmatically configure the system, you do not need to use a configuration file. If you use a configuration file, you must load that file into the system by calling RemotingConfiguration.Configure.

3. In the host, create the appropriate channel and register it with the system by calling ChannelServices.RegisterChannel. If you use a configuration file, then you must load that file into the system by calling RemotingConfiguration.Configure.

4. The host cannot run without the published class, but the way you build your host environment with your service's implementation depends on how you want to share the public interface of your service.

a) If you are implementing an XML Web service (using an HttpChannel with the default SOAP serialization), your client can obtain the information in three ways:

i. Using the Soapsuds tool (Soapsuds.exe) to extract the information from the endpoint.

ii. Downloading an assembly that contains the metadata. iii. Downloading the source code for an interface.

Page 190: CSharp Handout v1.0

Handout - C#

Page 190 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

b) If you are implementing another type of service (for example, using a TcpChannelobject) your client can obtain the information in two ways:

iv. Downloading an assembly that contains the metadata. v. Downloading the source code for an interface.

In either case, the way you package your service in your own hosting application domain will depend on how you want to publish the metadata necessary for others to consume the service.

Client Tasks

The following basic steps are required to consume any service for use from outside your application domain:

1. Design your client. a) Choose a client application domain. b) Determine the activation mode and either the client activation URL or the well-

known object URL of the remote type. c) Consider whether you need to register a channel and port. d) Obtain the remote type's metadata.

2. Implement your client application domain. Remoting hosts might be Windows Services, console applications, Windows Forms applications, Internet Information Services (IIS) processes, or ASP.NET applications. Requirements for each type of application vary, so you should read the documentation describing how to build the type of application you want to use. For more information, refer Windows Applicationsor ASP.NET Web Applications.

3. Configure the client remoting system with the activation mode and other type information, such as application name and object Uniform Resource Identifier (URI). If you want to programmatically configure the system, you do not need to use a configuration file. If you use a configuration file, you must load that file into the system by calling RemotingConfiguration.Configure.

4. Create the appropriate channel and register it with the system by calling ChannelServices.RegisterChannel. If you use a configuration file, you must load that file into the system by calling RemotingConfiguration.Configure.

Summary

Server activation is used when remote objects are not required to maintain any state between method calls.

Single Call objects service one and only one request coming in. These objects service multiple clients and hence share data by storing state

information between client invocations. Client activation objects are server-side objects that are activated upon request from

the client.

Test your Understanding

1. How do you make an object remotable? 2. What is the formatting type used by HTTP channel? 3. What is the formatting type used by TCP channel? 4. What is the namespace used for Remoting?

Page 191: CSharp Handout v1.0

Handout - C#

Page 191 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Session 50: Garbage Collection and Memory Management

Learning Objectives

After completing this session, you will be able to: Explain Memory Management Define Disposing and Destructor Explain Garbage Collection

Memory Management

Automatic memory management is one of the services that the common language runtime provides during Managed Execution. The common language runtime's garbage collector manages the allocation and release of memory for an application. For developers, this means that you do not have to write code to perform memory management tasks when you develop managed applications. Automatic memory management can eliminate common problems, such as forgetting to free an object and causing a memory leak, or attempting to access memory for an object that has already been freed.

Allocating Memory

When you initialize a new process, the runtime reserves a contiguous region of address space for the process. This reserved address space is called the managed heap. The managed heap maintains a pointer to the address where the next object in the heap will be allocated. Initially, this pointer is set to the managed heap's base address. All reference types are allocated on the managed heap. When an application creates the first reference type, memory is allocated for the type at the base address of the managed heap. When the application creates the next object, the garbage collector allocates memory for it in the address space immediately following the first object. As long as address space is available, the garbage collector continues to allocate space for new objects in this manner. Allocating memory from the managed heap is faster than unmanaged memory allocation. Because the runtime allocates memory for an object by adding a value to a pointer, it is almost as fast as allocating memory from the stack. In addition, because new objects that are allocated consecutively are stored contiguously in the managed heap, an application can access the objects very quickly.

Releasing Memory

The garbage collector's optimizing engine determines the best time to perform a collection based on the allocations being made. When the garbage collector performs a collection, it releases the memory for objects that are no longer being used by the application. It determines which objects are no longer being used by examining the application's roots. Every application has a set of roots. Each root either refers to an object on the managed heap or is set to null. An application's roots include global and static object pointers, local variables and reference object parameters on a thread's stack, and CPU registers. The garbage collector has access to the list of active roots that the just-in-time (JIT) compiler and the runtime maintain. Using this list, it examines an application's

Page 192: CSharp Handout v1.0

Handout - C#

Page 192 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

roots, and in the process creates a graph that contains all the objects that are reachable from the roots. Objects that are not in the graph are unreachable from the application's roots. The garbage collector considers unreachable objects garbage and will release the memory allocated for them. During a collection, the garbage collector examines the managed heap, looking for the blocks of address space occupied by unreachable objects. As it discovers each unreachable object, it uses a memory-copying function to compact the reachable objects in memory, freeing up the blocks of address spaces allocated to unreachable objects. Once the memory for the reachable objects has been compacted, the garbage collector makes the necessary pointer corrections so that the application's roots point to the objects in their new locations. It also positions the managed heap's pointer after the last reachable object. Note that memory is compacted only if a collection discovers a significant number of unreachable objects. If all the objects in the managed heap survive a collection, then there is no need for memory compaction. To improve performance, the runtime allocates memory for large objects in a separate heap. The garbage collector automatically releases the memory for large objects. However, to avoid moving large objects in memory, this memory is not compacted.

Generations and Performance

To optimize the performance of the garbage collector, the managed heap is divided into three generations: 0, 1, and 2. The runtime's garbage collection algorithm is based on several generalizations that the computer software industry has discovered to be true by experimenting with garbage collection schemes. First, it is faster to compact the memory for a portion of the managed heap than for the entire managed heap. Secondly, newer objects will have shorter lifetimes and older objects will have longer lifetimes. Lastly, newer objects tend to be related to each other and accessed by the application around the same time. The runtime's garbage collector stores new objects in generation 0. Objects created early in the application's lifetime that survive collections are promoted and stored in generations 1 and 2. The process of object promotion is described later in this topic. Because it is faster to compact a portion of the managed heap than the entire heap, this scheme allows the garbage collector to release the memory in a specific generation rather than release the memory for the entire managed heap each time it performs a collection. In reality, the garbage collector performs a collection when generation 0 is full. If an application attempts to create a new object when generation 0 is full, the garbage collector discovers that there is no address space remaining in generation 0 to allocate for the object. The garbage collector performs a collection in an attempt to free address space in generation 0 for the object. The garbage collector starts by examining the objects in generation 0 rather than all objects in the managed heap. This is the most efficient approach, because new objects tend to have short lifetimes, and it is expected that many of the objects in generation 0 will no longer be in use by the application when a collection is performed. In addition, a collection of generation 0 alone often reclaims enough memory to allow the application to continue creating new objects.

Page 193: CSharp Handout v1.0

Handout - C#

Page 193 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

After the garbage collector performs a collection of generation 0, it compacts the memory for the reachable objects as explained in Releasing Memory earlier in this topic. The garbage collector then promotes these objects and considers this portion of the managed heap generation 1. Because objects that survive collections tend to have longer lifetimes, it makes sense to promote them to a higher generation. As a result, the garbage collector does not have to reexamine the objects in generations 1 and 2 each time it performs a collection of generation 0. After the garbage collector performs its first collection of generation 0 and promotes the reachable objects to generation 1, it considers the remainder of the managed heap generation 0. It continues to allocate memory for new objects in generation 0 until generation 0 is full and it is necessary to perform another collection. At this point, the garbage collector's optimizing engine determines whether it is necessary to examine the objects in older generations. For example, if a collection of generation 0 does not reclaim enough memory for the application to successfully complete its attempt to create a new object, the garbage collector can perform a collection of generation 1, then generation 0. If this does not reclaim enough memory, the garbage collector can perform a collection of generations 2, 1, and 0. After each collection, the garbage collector compacts the reachable objects in generation 0 and promotes them to generation 1. Objects in generation 1 that survive collections are promoted to generation 2. Because the garbage collector supports only three generations, objects in generation 2 that survive a collection remain in generation 2 until they are determined to be unreachable in a future collection.

Releasing Memory for Unmanaged Resources

For the majority of the objects that your application creates, you can rely on the garbage collector to automatically perform the necessary memory management tasks. However, unmanaged resources require explicit cleanup. The most common type of unmanaged resource is an object that wraps an operating system resource, such as a file handle, window handle, or network connection. Although the garbage collector is able to track the lifetime of a managed object that encapsulates an unmanaged resource, it does not have specific knowledge about how to clean up the resource. When you create an object that encapsulates an unmanaged resource, it is recommended that you provide the necessary code to clean up the unmanaged resource in a public Dispose method. By providing a Dispose method, you enable users of your object to explicitly free its memory when they are finished with the object. When you use an object that encapsulates an unmanaged resource, you should be aware of Dispose and call it as necessary.

Garbage Collection:

The .NET Framework's garbage collector manages the allocation and release of memory for your application. Each time you use the new operator to create an object, the runtime allocates memory for the object from the managed heap. As long as address space is available in the managed heap, the runtime continues to allocate space for new objects. However, memory is not infinite. Eventually the garbage collector must perform a collection in order to free some memory. The garbage collector's optimizing engine determines the best time to perform a collection, based upon the allocations being made. When the garbage collector performs a collection, it 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. For the majority of the objects that your application creates, you can rely on the .NET Framework's garbage collector to implicitly perform all the necessary memory management tasks. However, when you create objects that encapsulate unmanaged resources, you must explicitly release the unmanaged resources when you are finished using them in your application. The most common

Page 194: CSharp Handout v1.0

Handout - C#

Page 194 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

type of unmanaged resource is an object that wraps an operating system resource, such as a file, window, or network connection. Although the garbage collector is able to track the lifetime of an object that encapsulates an unmanaged resource, it does not have specific knowledge about how to clean up the resource. For these types of objects, the .NET Framework provides the Object.Finalize method, which allows an object to clean up its unmanaged resources properly when the garbage collector reclaims the memory used by the object. By default, the Finalize method does nothing. If you want the garbage collector to perform cleanup operations on your object before it reclaims the object's memory, you must override the Finalize method in your class. The garbage collector keeps track of objects that have Finalize methods, using an internal structure called the finalization queue. Each time your application creates an object that has a Finalize method, the garbage collector places an entry in the finalization queue that points to that object. The finalization queue contains entries for all the objects in the managed heap that need to have their finalization code called before the garbage collector can reclaim their memory. Implementing Finalize methods or destructors can have a negative impact on performance and you should avoid using them unnecessarily. Reclaiming the memory used by objects with Finalize methods requires at least two garbage collections. When the garbage collector performs a collection, it reclaims the memory for inaccessible objects without finalizers. At this time, it cannot collect the inaccessible objects that do have finalizers. Instead, it removes the entries for these objects from the finalization queue and places them in a list of objects marked as ready for finalization. Entries in this list point to the objects in the managed heap that are ready to have their finalization code called. The garbage collector calls the Finalize methods for the objects in this list and then removes the entries from the list. A future garbage collection will determine that the finalized objects are truly garbage because they are no longer pointed to by entries in the list of objects marked as ready for finalization. In this future garbage collection, the objects' memory is actually reclaimed.

Cleaning up Unmanaged Resources

The users should be prevented from calling an object's Finalize method directly by limiting its scope to protected. In addition, you are strongly discouraged from calling a Finalize method for a class other than your base class directly from your application's code. To properly dispose of unmanaged resources, it is recommended that you implement a public Dispose or Close method that executes the necessary cleanup code for the object. The IDisposable interface provides the Dispose method for resource classes that implement the interface. Because it is public, users of your application can call the Dispose method directly to free memory used by unmanaged resources. When you properly implement a Dispose method, the Finalize method becomes a safeguard to clean up resources in the event that the Dispose method is not called.

Implementing a Dispose method

A type's Dispose method should release all the resources that it owns. It should also release all resources owned by its base types by calling its parent type's Dispose method. The parent type's Dispose method should release all resources that it owns and in turn call its parent type's Dispose method, propagating this pattern through the hierarchy of base types. To help ensure that resources are always cleaned up appropriately, a Dispose method should be callable multiple times without throwing an exception.

Page 195: CSharp Handout v1.0

Handout - C#

Page 195 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

A Dispose method should call the GC.SuppressFinalize method for the object it is disposing. If the object is currently on the finalization queue, GC.SuppressFinalize prevents its Finalize method from being called. Remember that executing a Finalize method is costly to performance. If your Dispose method has already done the work to clean up the object, then it is not necessary for the garbage collector to call the object's Finalize method. The purpose of the following code example is to illustrate the recommended design pattern for implementing a Dispose method for classes that encapsulate unmanaged resources. This pattern is implemented throughout the .NET Framework. // Design pattern for the base class.

// By implementing IDisposable, you are announcing that instances of this type allocate scarce resources.

public class BaseResource: IDisposable

{

private IntPtr handle;

private Component Components;

// Track whether Dispose has been called.

private bool disposed = false;

// Implement IDisposable.

// Do not make this method virtual. A derived class should not be able to override this method.

public void Dispose()

{

Dispose(true);

// Take yourself off the Finalization queue to prevent finalization code for this object

// from executing a second time.

GC.SuppressFinalize(this);

}

// Dispose(bool disposing) executes in two distinct scenarios. If disposing equals true, the method has been called directly or indirectly by a user's code. Managed and unmanaged resources can be disposed. If disposing equals false, the method has been called by the runtime from inside the finalizer and you should not reference other objects. Only unmanaged resources can be disposed.

protected virtual void Dispose(bool disposing)

{

// Check to see if Dispose has already been called.

if(!this.disposed)

{

// If disposing equals true, dispose all managed and unmanaged resources.

if(disposing)

Page 196: CSharp Handout v1.0

Handout - C#

Page 196 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

{

// Dispose managed resources.

Components.Dispose();

}

// Release unmanaged resources. If disposing is false, only the following code is executed.

CloseHandle(handle);

handle = IntPtr.Zero;

}

disposed = true;

}

// Use C# destructor syntax for finalization code. This destructor will run only if the Dispose method does not get called. It gives your base class the opportunity to finalize. Do not provide destructors in types derived from this class.

~BaseResource()

{

// Do not re-create Dispose clean-up code here. Calling Dispose(false) is optimal in terms of readability and maintainability.

Dispose(false);

}

// Allow your Dispose method to be called multiple times, but throw an exception if the object has been disposed. Whenever you do something with this class, check to see if it has been disposed.

public void DoSomething()

{

if(this.disposed)

{

throw new ObjectDisposedException();

}

}

}

// Design pattern for a derived class.

public class MyResourceWrapper: BaseResource

{

private ManagedResource addedManaged;

private NativeResource addedNative;

private bool disposed = false;

protected override void Dispose(bool disposing)

{

if(!this.disposed)

Page 197: CSharp Handout v1.0

Handout - C#

Page 197 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

{

try

{

if(disposing)

{

// Release the managed resources you added in this derived class here.

addedManaged.Dispose();

}

// Release the native unmanaged resources you added in this derived class here.

CloseHandle(addedNative);

this.disposed = true;

}

finally

{

// Call Dispose on your base class.

base.Dispose(disposing);

}

}

}

}

Using Objects that Encapsulate Resources

When you write code that uses an object that encapsulates a resource, you should make sure that the object's Dispose method gets called when you are finished using the object. You can do this with the C# using statement or by implementing a try/finally block in other languages that target the common language runtime.

C# Using Statement

The C# programming language's using statement makes a call to the Dispose method more automatic, by simplifying the code that you must write to create and clean up an object. The using statement obtains one or more resources, executes the statements that you specify, and then disposes of the object. Note that the using statement is only useful for objects with a lifetime that does not extend beyond the method in which the objects are constructed. The following code example creates and cleans up an instance of the ResourceWrapper class, as illustrated in the C# example of implementing a Dispose method. class myApp

{

public static void Main()

{

using (ResourceWrapper r1 = new ResourceWrapper())

{

// Do something with the object.

r1.DoSomething();

}

Page 198: CSharp Handout v1.0

Handout - C#

Page 198 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

}

}

The preceding code, incorporating the using statement, is equivalent to the following. class myApp

{

public static void Main()

{

ResourceWrapper r1 = new ResourceWrapper();

try

{

// Do something with the object.

r1.DoSomething();

}

finally

{

// Check for a null resource.

if (r1 != null)

// Call the object's Dispose method.

r1.Dispose();

}

}

}

Forcing a Garbage Collection

The garbage collection GC class provides the GC.Collect method, which you can use to give your application some direct control over the garbage collector. In general, you should avoid calling any of the collect methods and allow the garbage collector to run independently. In most cases, the garbage collector is better at determining the best time to perform a collection. In certain rare situations, however, forcing a collection might improve your application's performance. It might be appropriate to use the GC.Collect method in a situation where there is a significant reduction in the amount of memory being used at a defined point in your application's code. For example, an application might use a document that references a significant number of unmanaged resources. When your application closes the document, you know definitively that the resources the document has been using are no longer needed. For performance reasons, it makes sense to release them all at once. For more information, see the GC.Collect Method. Before the garbage collector performs a collection, it suspends all currently executing threads. This can become a performance issue if you call GC.Collect more often than is necessary. You should also be careful not to place code that calls GC.Collect at a point in your program where users could call it frequently. This would defeat the optimizing engine in the garbage collector, which determines the best time to run a garbage collection.

Page 199: CSharp Handout v1.0

Handout - C#

Page 199 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

The following tables list the members exposed by the GC type. Public Properties:

Name Description

MaxGeneration Gets the maximum number of generations the system currently supports.

Public Methods:

Name Description

AddMemoryPressure Informs the runtime of a large allocation of unmanaged memory that should be taken into account when scheduling garbage collection.

Collect Overloaded. Forces garbage collection.

CollectionCount Returns the number of times garbage collection has occurred for the specified generation of objects.

Equals Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

GetGeneration Overloaded. Returns the current generation number of an object.

GetHashCode Serves as a hash function for a particular type. GetHashCode is suitable for use in hashing algorithms and data structures like a hash table. (Inherited from Object.)

GetTotalMemory Retrieves the number of bytes currently thought to be allocated. A parameter indicates whether this method can wait a short interval before returning, to allow the system to collect garbage and finalize objects.

GetType Gets the Type of the current instance. (Inherited from Object.)

KeepAlive References the specified object, making it ineligible for garbage collection from the start of the current routine to the point where this method is called.

ReferenceEquals Determines whether the specified Object instances are the same instance. (Inherited from Object.)

RemoveMemoryPressure Informs the runtime that unmanaged memory has been released and no longer needs to be taken into account when scheduling garbage collection.

ReRegisterForFinalize Requests that the system call the finalizer for the specified object, for which SuppressFinalize has previously been called.

Page 200: CSharp Handout v1.0

Handout - C#

Page 200 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Name Description

SuppressFinalize Requests that the system not call the finalizer for the specified object.

ToString Returns a String that represents the current Object. (Inherited from Object.)

WaitForPendingFinalizers

Suspends the current thread until the thread processing the queue of finalizers has emptied that queue.

Summary

Memory Management: Keeping track of memory used by the program and reclaim the memory space when they are no longer used.

Disposing: It is the tasks associated with freeing, releasing or resetting unmanaged resources.

Destructors: It is a member that implements the actions required to destruct an instance of a class.

Garbage Collection: It is a process by which you can dynamically allocated storage is reclaimed during the execution of a program.

Test your Understanding

1. Which object implements Garbage Collection in .Net? 2. Which method forces Garbage collection? 3. How many generations are available in .Net? 4. Where are objects created in the memory?

a) Stack b) Heap

5. Which statement implements Dispose functionality automatically in C#?

Page 201: CSharp Handout v1.0

Handout - C#

Page 201 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Glossary Access modifiers: Language keywords used to specify the visibility of the methods and member variables declared within a class. The five access modifiers in the C# language are public, private, protected, internal, and protected internal. Application domain: The logical and physical boundary created around every .NET application by the CLR. The CLR can allow multiple .NET applications to be run in a single process by loading them into separate application domains. The CLR isolates each application domain from all other application domains and prevents the configuration, security, or stability of running .NET applications from affecting other applications. Objects can only be moved between application domains by the use of remoting. Application Manifest: The part of an application that provides information to describe the components that the application uses. Array: A collection of objects of the same type, all of which are referenced by a single identifier and an indexer. In the .NET Framework, all arrays inherits from the Array class that is located in the System namespace. Assembly: All of the files that comprise a .NET application, including the resource, security management, versioning, sharing, deployment information, and the actual MSIL code executed by the CLR. An assembly may appear as a single DLL or EXE file, or as multiple files, and is roughly the equivalent of a COM module. See assembly manifest, private assembly, shared assembly. Assembly cache: A reserved area of memory used to store the assemblies of a .NET applications running on a specific machine. See Global Assembly Cache. Assembly manifest: A detailed description of the contents of an assembly. A manifest contains metadata describing the name, version, types, and resources in the assembly, and the dependencies upon other assemblies. The manifest allows an assembly to be self-describing, easily deployed, and not bound to a particular system by storing information in the Windows registry. Assembly Registration Tool: A .NET programming tool (RegAsm.exe) used to register an assembly in the Windows registry. Registration is required if COM clients need to call managed methods residing in a .NET assembly. This tool can also be used to generate a registry (.reg) file containing the necessary registration information. Registration typically only occurs once when the assembly is installed. Base class: The parent class of a derived class. Classes may be used to create other classes. A class that is used to create (or derive) another class is called the base class or super class. See Derived Class, Inheritance.

Page 202: CSharp Handout v1.0

Handout - C#

Page 202 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Boxing; Conversion of a value type to a reference type object (that is, System.Object). Value types are stored in stack memory and must be converted (that is, boxed) to a new object in heap memory before they can be manipulated as objects. The methods, functions, and events of the new object are invoked to perform operations on the value (for example, converting an integer to a string). Boxing is implicitly performed by the CLR at runtime. Refer Unboxing. Callback Method: A method used to return the results of an asynchronous processing call. Typically, methods are called in a synchronous fashion, where the call does not return until the results (that is, the output or return value) of the call are available. An asynchronous method call returns prior to the results, and then sometime later a callback method is called to return the actual results. The callback method itself contains program statements that are executed in response to the reception of the results. It is also referred to as a callback function under the Win32 API. Refer Event. Casting: Conversion of a value from one type to another. Implicit casting is performed silently by the compiler when the casting would not cause any information to be lost (For example, converting a 16-bit integer to a 32-bit integer value). Explicit casting is coded by the programmer using the particular language's cast operator. This is necessary when the use of a value would cause a possible loss of data (For example, converting a 32-bit integer to a 16-bit integer value). Catching: To trap a program exception. See try/catch block. COM (Component Object Model): A software architecture developed by Microsoft to build component-based applications. COM objects are discrete components, each with a unique identity, which expose interfaces that allow applications and other components to access their features. COM objects are more versatile that Win32 DLLs because they are completely language independent, have built-in interprocess communications capability, and easily fit into an Object-Oriented program design. COM was first released in 1993 with OLE2, largely to replace the interprocess communication mechanism Dynamic Data Exchanged (DDE) used by the initial release of OLE. Refer COM+. COM+: The "next generation" of the COM and DCOM software architectures. COM+ (pronounced "COM plus") makes it easier to design and construct distributed, transactional, and component-based applications using a multi-tiered architecture. COM+ also supports the use of many new services, such as Just-in-Time Activation, object pooling, and Microsoft Transaction Server (MTS) 2.0. The use of COM, DCOM, and COM+ in application design will eventually be entirely replaced by the Microsoft .NET Framework. COM Callable Wrapper (CCW): A metadata wrapper that allows COM components to access managed .NET objects. The CCW is generated at runtime when a COM client loads a .NET object. The .NET assembly must first be registered using the Assembly Registration Tool. Refer Runtime Callable Wrapper (RCW). Class: In .NET languages, classes are templates used for defining new types. Classes describe both the properties and behaviors of objects. Properties contain the data that are exposed by the class. Behaviors are the functionality of the object, and are defined by the public methods (also called member functions) and events of the class. Collectively, the public properties and methods of a class are known as the object interface. Classes themselves are not objects, but instead they are used to instantiate (that is, create) objects in memory. Refer structure.

Page 203: CSharp Handout v1.0

Handout - C#

Page 203 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Common Intermediate Language (CIL): The system-independent code generated by a .NET language compiler. CIL defines a file format for storing managed code as both program instructions and metadata in a single file. Either the ILASM assembler or JIT compiler is then used to convert CIL to native machine code. CIL is also referred to as Microsoft Intermediate Language (MSIL). Common Language Infrastructure (CLI): The .NET infrastructure that allows applications written in multiple programming languages to operate many different environments without the need to modify the program code. The CLI consists of a file format (PE), a common type system (CTS), an extensible metadata system, an intermediate language (CIL), a factored base class library (FCL), and access to the underlying operating system (Win32). The CLI is defined by the standard ECMA-335. Common Language Runtime (CLR): A runtime environment that manages the execution of .NET program code, and provides services such as memory and exception management, debugging and profiling, and security. The CLR is a major component of the .NET Framework, and provides much of its functionality by following the rules defined in the Common Type System. Also known as the Virtual Execution System (VES). Common Language Specification (CLS): A set of common conventions used to promote interoperability between programming languages and the .NET Framework. The CLS specifies a subset of the Common Type System and set of conventions that are adhered to by both programming language designers and framework class library authors. Common Type System (CTS): The .NET Framework specification which defines the rules of how the Common Language Runtime defines, declares, and manages types, regardless of the programming language. All .NET components must comply with the CTS specification. Constructor: A method that is automatically called when an object is created. The constructor is used to initialize the object and place it in a valid state (For example, setting the values of member variables). The constructor method always has the same identifier as the class in which it is defined. Refer Destructor. DCOM (Distributed Component Object Model): An extension of the Microsoft Component Object Model (COM) that allows COM components to communicate across network boundaries. Traditional COM components can only perform interprocess communication across process boundaries on the same machine. DCOM uses the Remote Procedure Call (RPC) mechanism to transparently send and receive information between COM components (that is, clients and servers) on the same network. DCOM was first made available in 1995 with the initial release of Windows NT 4. Delegate: A mechanism used to implement event handling in .NET Framework code. A class that needs to raise events must define one delegate per event. Types that use the class must implement one event handler method per event that must be processed. Delegates are often described as a managed version of a C++ function pointer. However, delegates can reference both instance and static (also called shared) methods, while function pointers can only reference static methods.

Page 204: CSharp Handout v1.0

Handout - C#

Page 204 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Derived class: A class that was created based on a previously existing class (that is, base class). A derived class inherits all of the member variables and methods of the base class it is derived from. It is also called a derived type. Destructor: In traditional Object Oriented Programming, a destructor is a class method that is called when an object goes out of scope. In .NET languages, the destructor method is instead called when the object is garbage collected by the CLR - which happens at some indeterminate time after an object goes out of scope. In C#, the destructor is actually a syntactic mapping to a Finalize method. Refer Constructor, Dispose. Dispose: A class-only method used to implement an explicit way to release the resources allocated by an object. The dispose method is actually in implementation of the IDisposable interface, and is typically called by the destructor or Finialize method of a class. Event: A notification by a program or operating system that "something has happened." An event may be fired (or raised) in response to the occurrence of a pre-defined action (for example, a window getting focus, a user clicking a button, a timer indicating a specific interval of time has passed, or a program starting up or shutting down). In response to an event, an event handler is called. Event Handler: A function or method containing program statements that are executed in response to an event. Refer Callback method. Exception: A signal that is generated when an unplanned or unexpected event occurs. Exceptions are typically caught by an exception handler and dealt with in an appropriate way. A fatal exception (also called a critical or catastrophic error) is an event that cannot be properly handled to allow the application - or the operating system - to continue running. Exception Handling: The process of trapping an exception and performing some sort of corrective procedure in response. Refer try/catch block. Finalize: A class-only method that is automatically called when an object is destroyed by the garbage collector. The Finalize method is primarily used to free up unmanaged resources allocated by the object before the object itself is removed from memory. A Finalize method is not needed when only managed resources are used by the object, which are automatically freed by the garbage collector. In C#, when a destructor is defined in a class it is mapped to a Finalize method. It is also called a finalizer. Refer Dispose. Finally block: A block of program statements that will be executed regardless if an exception is thrown or not. A finally block is typically associated with a try/catch block (although a catch block need not be present to use a finally block). This is useful for operations that must be performed regardless if an exception was thrown or not (For example, closing a file, writing to a database, deallocating unmanaged memory, and so on). Framework Class Library (FCL): The collective name for the thousands of classes that compose the .NET Framework. The services provided by the FCL include runtime core functionality (basic types and collections, file and network I/O, accessing system services, and so on.), interaction with

Page 205: CSharp Handout v1.0

Handout - C#

Page 205 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

databases, consuming and producing XML, and support for building Web-based (Web Form) and desktop-based (Windows Form) client applications, and SOAP-based XML Web services. Garbage Collection (GC): The process of implicitly reclaiming unused memory by the CLR. Stack values are collected when the stack frame they are declared within ends (For example, when a method returns). Heap objects are collected sometime after the final reference to them is destroyed. Global Assembly Cache (GAC): A reserved area of memory used to store the assemblies of all of the .NET applications running on a specific machine. The GAC is necessary for side-by-side execution and for the sharing of assemblies among multiple applications. To reside in the GAC, an assembly must be public (that is, a shared assembly) and have a strong name. Assemblies are added and removed from the GAC using the Global Assembly Cache Tool. Heap: An area of memory reserved for use by the CLR for a running programming. In .NET languages, reference types are allocated on the heap. Refer Stack Indexer: A CLR language feature that allows array-like access to the properties of an object using getter and setter methods and an index value. This construct is identical to operator[] in C++. Refer Property. Inheritance: The ability of a class to be created from another class. The new class, called a derived class or subclass, is an exact copy of the base class or superclass and may extend the functionality of the base class by both adding additional types and methods and overriding existing ones. Just In Time (JIT): The concept of only compiling units of code just as they are needed at runtime. The JIT compiler in the CLR compiles MSIL instructions to native machine code as a .NET application is executed. The compilation occurs as each method is called; the JIT-compiled code is cached in memory and is never recompiled more than once during the program's execution. Managed code: It is the code that is executed by the CLR. Managed code provides information (that is, metadata) to allow the CLR to locate methods encoded in assembly modules, store and retrieve security information, handle exceptions, and walk the program stack. Managed code can access both managed data and unmanaged data. MSIL (Microsoft Intermediate Language): The machine-independent language into which .NET applications are compiled using a high-level .NET language compiler (For example, C# and VB.NET). The MSIL output is then used as the input of the Just-In-Time (JIT) compiler, which compiles the MSIL instructions to machine language just prior to its execution. MSIL can also be converted to native machine object code using the Native Image Generator utility. Namespace: A logical grouping of the names (that is, identifiers) used within a program. A programmer defines multiple namespaces as a way to logically group identifiers based on their use. For example, System.Drawing and System.Windows are two namespaces containing each containing types used for different purposes. The name used for any identifier may only appear once in any namespace. A namespace only contains the name of a type and not the type itself. Also called name scope.

Page 206: CSharp Handout v1.0

Handout - C#

Page 206 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Native code: Machine-readable instructions that are created for a specific CPU architecture. Native code for a specific family of CPUs is not usable by a computer using different CPU architectures (c.f., Intel x86 and Sun UltraSPARC). It is also called object code and machine code. Native Image Generator: A .NET programming tool (Ngen.exe) used to compile a managed assembly to native machine code and install it in the local assembly cache. During execution the native image will be used each time the assembly is accessed rather than the MSIL assembly itself. If the native image is removed, the CLR reverts to using the original MSIL assembly by default. Native images are faster to load and execute than MSIL assemblies, which must be Just-In-Time (JIT) compiled by the CLR. Using Ngen to create a native image file is often referred to as pre-JITting, because it makes JIT-compiling the assembly unnecessary. Object: The instance of a class that is unique and self-describing. A class defines an object, and an object is the functional, realization of the class. Analogously, if a class is a cookie cutter then the cookies are the objects the cutter was used to create. Private assembly: An assembly that is used only by a single application. A private assembly will run only with the application with which it was built and deployed. References to the private assembly will only be resolved locally to the application directory it is installed in. Refer Shared assembly. Pointer: A variable that contains the address of a location in memory. The location is the starting point of an allocated object, such as an object or value type, or the element of an array. Reference types: A variable that stores a reference to data located elsewhere in memory rather than to the actual data itself. Reference types include array, class, delegate, and interface. Refer Value types, Pointer types. Reflection: A feature that allows an application to query its own metadata. Reflection (System.Reflection) allows an application to discover information about itself so that it may display this information to the user, modify its own behavior by using late-binding and dynamic invocation (that is, binding to and calling methods at runtime), or create new types at runtime (Reflection Emit). Remoting: A .NET technology that allows objects residing in different application domains to communicate. Objects in different application domains are said to be separated by a remoting boundary. Objects using remoting may be on the same computer, or on different computers connected by a network. Remoting is the .NET replacement for Distributed COM (DCOM). Runtime Callable Wrapper (RCW)L: A metadata wrapper that allows COM components to be called from .NET applications. For OLE automation interfaces, an RCW is a managed .NET assembly that is generated from the COM component's type library using the Type Library Importer tool. For non-OLE automation interfaces, a custom RCW must be written that manually maps the types exposed by the COM interface to .NET Framework-compatible types. Refer COM Callable Wrapper (CCW). Stack: An area of program memory used to store local program variables, method parameters, and return values. In .NET languages, value types are allocated on the stack. Refer Heap.

Page 207: CSharp Handout v1.0

Handout - C#

Page 207 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

Strong name: An assembly name that is globally unique among all .NET assemblies. A public key encryption scheme is used to create a digital signature to insure that the strong name is truly different than all other names created at anytime and anywhere in the known universe. The digital signature also makes it easy to encrypt the assembly, authenticate who created the assembly, and to validate that the assembly has not been corrupted or tampered with. Strong names are created using the Shared name utility. Try/Catch block: An exception handling mechanism in program code. A try block contains a set of program statements that may possibly throw an exception when executed. The associated catch block contains program statements that handle any exception that is thrown in the try block. Multiple catch blocks may be defined to catch specific exceptions (For example, divide by zero, overflow, and so on.). Refer Finally block. Unmanaged: An adjective generally applied to any code or data that is outside of the control of a runtime host environment. In .NET, any objects or resources not allocated and controlled by the CLR are considered unmanaged (For example, Windows handles and calls to the Win32 API). Unmanaged code: Any code that executes outside of the control of the .NET Common Language Runtime. Unmanaged code may perform unsafe operations, such as declare and operate on pointers, take the address of a variable, and perform conversions between pointers and integral types. Uses of unmanaged code include calling operating system APIs, interfacing to COM components, accessing unmanaged areas of memory, and writing performance-critical routines that are not encumbered by the overhead of the CLR. It is also called as unsafe code. Value types: A variable that stores actual data rather than a reference to data, which is stored elsewhere in memory. Simple value types include the integer, floating point number, decimal, character, and Boolean types. Value types have the minimal memory overhead and are the fastest to access. Refer Reference types, Pointer types. XML Schema: A description of the structure of an XML document. Schemas are written in XSD and support namespaces and data types. XPath (XML Path Language): A language that uses path expressions to specify the locations of structures and data within an XML document. XPath information is processed using XSLT or XPointer. See the document XML Path Language (XPath) Version 1.0.

Page 208: CSharp Handout v1.0

Handout - C#

Page 208 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

References

Websites

Visual C# Developer Center: o http://msdn.microsoft.com/vcsharp/

.NET Framework Developer Center o http://msdn.microsoft.com/netframework/

MSDN Columns o http://msdn.microsoft.com/columns/

MSDN Academic Alliance: o http://www.msdnaa.net/

Books

ECMA C# Language Specification. Professional C#, 2nd Edition. Simon Robinson. Wrox. Learning C#. Jesse Liberty. O'Reilly. Inside C#. Tom Archer. Microsoft Press. C# Essentials. Ben Albahari, Peter Drayton & Brad Merrill. O'Reilly.

Page 209: CSharp Handout v1.0

Handout - C#

Page 209 ©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved

C3: Protected

STUDENT NOTES: