Sie sind auf Seite 1von 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

Handout - C#

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 2 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 3 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 4 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 5 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 6 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 7 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 8 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 9 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 builtin (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 10 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 11 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 12 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 itemsthe assembly name, version number, culture, and strong name informationmake up the assembly's identity.

Information Assembly name Version number Culture

Description A text string specifying the assembly's name. A major and minor version number, and a revision and build number. The common language runtime uses these numbers to enforce version policy. 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.) The public key from the publisher if the assembly has been given a strong name. 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. 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. 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.

Strong name information List of all files in the assembly Type reference information Information on referenced assemblies

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 13 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 14 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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

Runtime Host
ASP.NET

Description
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. 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. Invokes runtime hosting code to transfer control to the runtime each time an executable is launched from the shell.

Microsoft Internet Explorer

Shell executables

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 15 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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

Page 16 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 17 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 forstatement, 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 Causes the program control to be transferred to a specific flow based upon whether a certain condition is true or not. 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. Branching is performed using jump statements, which cause an immediate transfer of the program control. 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. C# keywords if, else, switch, case do, for, foreach, in, while 1. Selection statements 2. Iteration statements

3. Jump statements 4. Exception handling statements

break, continue, default, goto, return, yield throw, trycatch, tryfinally, trycatch-finally

Page 18 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No

Category

Purpose 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. 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. 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.

C# keywords checked, unchecked

5. Checked and unchecked

6. fixed Statement

fixed

7. lock Statement

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 19 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 20 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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; static short y = 32767;

// Max short value

// 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 21 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 22 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 23 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

The following table provides the list of keywords in C#: abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while

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 24 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Console.ReadLine(); } } }

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

Identifiers: Identifiers are names used to denote variables, constants, types, methods, objects, and so on. Keywords: o o Keywords are special words built into the C# language and are reserved for specific use. 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. 2. 3. 4. 5. What are the types of statements and explain its syntax? How do you give valid names in C#? Give some examples. List some of the keywords in C#. What is an Identifier? Can a variable name contain special characters?

Page 25 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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. Type int Range 2,147,483,648 to 2,147,483,647 Size Signed 32-bit integer .NET Framework type System.Int32

You can declare and initialize a variable of the type int like this: int intVar=534; Members: Public Fields: S.No 1 2 Name MaxValue MinValue Description Represents the largest possible value of an Int32. This field is constant. Represents the smallest possible value of an Int32. This field is constant.

Public Methods: S.No 1 2 3 4 5 6 Name CompareTo Equals GetHashCode GetType GetTypeCode Parse Description Overloaded. Compares this instance to a specified object or Int32 and returns an indication of their relative values. Overloaded. Returns a value indicating whether this instance is equal to a specified object or Int32. Overridden. Returns the hash code for this instance. Gets the Type of the current instance. (Inherited from Object.) Returns the TypeCode for value type Int32. Overloaded. Converts the string representation of a number to its 32-bit signed integer equivalent.

Page 26 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 7 8 9

Name ReferenceEquals ToString TryParse

Description Determines whether the specified. Object instances are the same instance. (Inherited from Object.) Overloaded. Overridden. Converts the numeric value of this instance to its equivalent string representation. 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. Type long Range -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 Size Signed 64-bit integer .NET Framework type System.Int64

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. Type double Approximate Range 5.0 10324 to 1.7 10308 Precision 15-16 digits .NET Framework type System. Double

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 1 2 3 4 5 6 Name MaxValue MinValue Epsilon NaN NegativeInfinity PositiveInfinity Description Represents the largest possible value of a Double. This field is constant. Represents the smallest possible value of a Double. This field is constant. Represents the smallest positive Double greater than zero. This field is constant. Represents a value that is not a number (NaN). This field is constant. Represents negative infinity. This field is constant. Represents positive infinity. This field is constant.

Page 27 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Public Methods: S.No 1 2 3 4 5 6 7 8 9 10 11 12 13 Name CompareTo Equals GetHashCode GetType GetTypeCode IsInfinity IsNaN IsNegativeInfinity IsPositiveInfinity Parse ReferenceEquals ToString TryParse Description Overloaded. Compares this instance to a specified object or Double and returns an indication of their relative values. Overloaded. Returns a value indicating whether this instance is equal to a specified object or Double. Overridden. Returns the hash code for this instance. Gets the Type of the current instance. (Inherited from Object.) Returns the TypeCode for value type Double. Returns a value indicating whether the specified number evaluates to negative or positive infinity Returns a value indicating whether the specified number evaluates to a value that is not a number (NaN). Returns a value indicating whether the specified number evaluates to negative infinity. Returns a value indicating whether the specified number evaluates to positive infinity. Overloaded. Converts the string representation of a number to its double-precision floating point number equivalent Determines whether the specified Object instances are the same instance. (Inherited from Object) Overloaded. Overridden. Converts the numeric value of this instance to its equivalent string representation. 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. Type Char Range U+0000 to U+ffff Size Unicode 16-bit character .NET Framework type System.Char

You can declare and initialize a char variable like this: char charVar = a; Members: Public Fields: S.No 1 2 Name MaxValue MinValue Description Represents the largest possible value of a char. This field is constant. Represents the smallest possible value of a char. This field is constant.

Page 28 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Public Methods: S.No 1 2 3 4 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Name CompareTo ConvertFromUtf32 ConvertUtf32 Equals GetHashCode GetNumericValue GetType GetTypeCode GetUnicodeCategory IsControl IsDigit IsHighSurrogate IsLetter IsSurrogatePair IsSymbol IsUpper IsWhiteSpace Parse ReferenceEquals ToLower TolowerInvariant ToString Description Overloaded. Compares this instance to a specified object or value type, and returns an indication of their relative values. Converts the specified Unicode code point into a UTF-16 encoded string. Overloaded. Converts the value of a UTF-16 encoded surrogate pair into a Unicode code point. Overloaded. Overridden. Returns the hash code for this instance. Overloaded. Converts a specified numeric Unicode character to a double-precision floating point number. Gets the Type of the current instance. (Inherited from Object) Returns the TypeCodefor value type Char. Overloaded. Categorizes a Unicode character into a group identified by one of the UnicodeCategory values. Overloaded. Indicates whether a specified Unicode character is categorized as a control character. Overloaded. Indicates whether a Unicode character is categorized as a decimal digit. Overloaded. Indicates whether the specified Char object is a high surrogate. Overloaded. Indicates whether a Unicode character is categorized as an alphabetic letter. Overloaded. Indicates whether two specified Char objects form a surrogate pair. Overloaded. Indicates whether a Unicode character is categorized as a symbol character. Overloaded. Indicates whether a Unicode character is categorized as an uppercase letter. Overloaded. Indicates whether a Unicode character is categorized as white space. Converts the value of the specified string to its equivalent Unicode character. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Overloaded. Converts the value of a Unicode character to its lowercase equivalent. Converts the value of a Unicode character to its lowercase equivalent using the casing rules of the invariant culture. Overloaded. Overridden. Converts the value of this instance to its equivalent string representation.

Page 29 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 22 23 24

Name ToUpper ToUpperInvariant TryParse

Description Overloaded. Converts the value of a Unicode character to its uppercase equivalent. Converts the value of a Unicode character to its uppercase equivalent using the casing rules of the invariant culture. 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 1 Name Empty Description Represents the empty String. This field is read only.

Public Properties: S.No 1 2 Name Chars Length Description Gets the character at a specified character position in this instance. Gets the number of characters in this instance.

Public Methods: S.No 1 2 3 4 5 Name Clone Compare CompareOrdinal CompareTo Concat Description Returns a reference to this instance of String. Overloaded. Compares two specified String objects. Overloaded. Compares two String objects by evaluating the numeric values of the corresponding Char objects in each string. Overloaded. Compares this instance with a specified object or String and returns an indication of their relative values. . Overloaded. Concatenates one or more instances of String, or the String representations of the values of one or more instances of Object. Returns a value indicating whether the specified String object occurs within this string. Creates a new instance of String with the same value as a specified String. Copies a specified number of characters from a specified position in this instance to a specified position in an array of Unicode characters.

6 7 8

Contains Copy CopyTo

Page 30 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 9 10 11 12 13 14 15 16 17

Name EndsWith Equals Format GetEnumerator GetHashCode GetType GetTypeCode IndexOf IndexOfAny

Description Overloaded. Determines whether the end of an instance of String matches a specified string. Overloaded. Overridden. Determines whether two String objects have the same value. Overloaded. Replaces each format item in a specified String with the text equivalent of a corresponding object's value. Retrieves an object that can iterate through the individual characters in this string. Overridden. Returns the hash code for this string. Gets the Type of the current instance. (Inherited from Object.) Returns the TypeCode for class String. Overloaded. Reports the index of the first occurrence of a String, or one or more characters, within this string. Overloaded. Reports the index of the first occurrence in this instance of any character in a specified array of Unicode characters. Inserts a specified instance of String at a specified index position in this instance. Retrieves the system's reference to the specified String. Retrieves a reference to a specified String. Overloaded. Indicates whether this string is in a particular Unicode normalization form. Indicates whether the specified String object is a null reference (Nothing in Visual Basic) or an Empty string. Overloaded. Concatenates a specified separator String between each element of a specified String array, yielding a single concatenated string. Overloaded. Reports the index position of the last occurrence of a specified Unicode character or String within this instance. Overloaded. Reports the index position of the last occurrence in this instance of one or more characters specified in a Unicode array. Overloaded. Returns a new string whose binary representation is in a particular Unicode normalization form. Determines whether two specified String objects have the same value. Determines whether two specified String objects have different values.

18 19 20 21 22 23

Insert Intern IsInterned IsNormalized IsNullorEmpty Join

24 25

LastIndexOf LastIndexOfAny

26 27 28

Normalize Op_Equality Op_InEquality

Page 31 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 29

Name PadLeft

Description Overloaded. Right-aligns the characters in this instance, padding on the left with spaces or a specified Unicode character for a specified total length. Overloaded. Left-aligns the characters in this string, padding on the right with spaces or a specified Unicode character, for a specified total length. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Overloaded. Deletes a specified number of characters from this instance. Overloaded. Replaces all occurrences of a specified Unicode character or String in this instance, with another specified Unicode character or String. Overloaded. Returns a String array containing the substrings in this instance that are delimited by elements of a specified Char or String array. Overloaded. Determines whether the beginning of an instance of String matches a specified string. Overloaded. Retrieves a substring from this instance. Overloaded. Copies the characters in this instance to a Unicode character array. Overloaded. Returns a copy of this String converted to lowercase. Returns a copy of this String object converted to lowercase using the casing rules of the invariant culture. Overloaded. Overridden. Converts the value of this instance to a String. Overloaded. Returns a copy of this String converted to uppercase. Returns a copy of this String object converted to uppercase using the casing rules of the invariant culture. Overloaded. Removes all occurrences of a set of specified characters from the beginning and end of this instance. Removes all occurrences of a set of characters specified in an array from the end of this instance. Removes all occurrences of a set of characters specified in an array from the beginning of this instance.

30

PadRight

31 32 33

ReferenceEquals Remove Replace

34

Split

35 36 37 38 39 40 41 42 43 44 45

StartsWith SubString ToCharArray ToLower ToLowerInvariant ToString ToUpper ToUpperInvariant Trim TrimEnd TrimStart

Page 32 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 33 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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; object box = i; int j = (int)box; // A value type // Boxing // 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 34 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

} 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 1 2 3 4 5 6 7 8 9 10 11 12 Operator Category Arithmetic Logical String Concatenation Increment, Decrement Shift Relational Assignment Member access Indexing Cast Conditional Delegate Concatenation and Removal Object creation Type information Indirection and Address + , & - , | + ++ , -<< == = = . [ ] () ?: + , >> != += *= < /= > %= <= &= >= |= ^= <<= >>= ?? ^ * , ! Operators / , % ~ && || true false

13 14 16

new as , is , Typeof() , sizeof() * , -> , [ ] , &

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 35 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 Primary Unary Multiplicative Additive Shift Relational and type testing Equality Logical AND Logical XOR Logical OR Conditional AND Conditional OR Conditional Assignment = *= /= %= += < > x.y f(x) + Operators a[x] x++ x-- new typeof checked unchecked ! ~ * ++x / + << <= == & ^ | && || ?: -= |= <<= >>= &= ^= >> >= != is as % --x (T)x Associability Left Left Left Left Left Left Right Left Left Left Left Left Right 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 36 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 1 2 3 4 5 6 7 Operators +, -, !, ~, ++, -, true, false +, -, *, /, %, &, |, ^, <<, >> ==, !=, <, >, <=, >= &&, || [ ] () +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= =, ., ?:, ->, new, is, sizeof, typeof Overloadability These unary operators can be overloaded. These binary operators can be overloaded. The comparison operators can be overloaded The conditional logical operators cannot be overloaded, but they are evaluated using & and |, which can be overloaded. The array indexing operator cannot be overloaded, but you can define indexers. The cast operator cannot be overloaded, but you can define new conversion operators (see explicit and implicit). Assignment operators cannot be overloaded, but +=, for example, is evaluated using +, which can be overloaded. 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 1 2 3 Category Selection statements Iteration statements Jump statements C# keywords if, else, switch, case do, for, foreach,, while 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 37 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

{ 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 38 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 39 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 40 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

static void Main() { int n = 1; while (n < 6) { Console.WriteLine("Current value of n is {0}", n); n++; } } } Jump Statementsbreak: 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 41 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 42 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 43 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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

Page 44 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 languagesbecause they are objects. This provides them with builtin 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 45 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 46 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 twodimensional 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. 1 2 3 4 5 6 7 Name IsFixedSize IsReadOnly IsSynchronized Length LongLength Rank SyncRoot Description Gets a value indicating whether the Array has a fixed size. Gets a value indicating whether the Array is read-only. Gets a value indicating whether access to the Array is synchronized (thread safe). Gets a 32-bit integer that represents the total number of elements in all the dimensions of the Array. Gets a 64-bit integer that represents the total number of elements in all the dimensions of the Array. Gets the rank (number of dimensions) of the Array. Gets an object that can be used to synchronize access to the Array.

Page 47 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Public Properties: S.No. 1 2 3 Name AsReadOnly BinarySearch Clear Description Returns a read-only wrapper for the specified array. Overloaded. Searches a one-dimensional sorted Array for a value, using a binary search algorithm. 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. Creates a shallow copy of the Array. 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. Converts an array of one type to an array of another type. Overloaded. Copies a range of elements in one Array to another Array and performs type casting and boxing as required. Overloaded. Copies all the elements of the current onedimensional Array to the specified one-dimensional Array. Overloaded. Initializes a new instance of the Array class. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) Determines whether the specified array contains elements that match the conditions defined by the specified predicate. Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire Array. Retrieves all the elements that match the conditions defined by the specified predicate. Overloaded. Searches for an element that matches the conditions defined by the specified predicate, and returns the last occurrence within the entire Array. Overloaded Performs the specified action on each element of the specified array. Returns an IEnumerator for the Array. 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.) 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 5

Clone ConstrainedCopy

6 7 8 9 10 11 12

ConvertAll Copy CopyTo CreateInstance Equals Exists Find

13 14 15

FindAll FindIndex FindLast

16 17 18 19

FindLastIndex ForEach GetEnumerator GetHashCode

20

GetLength

Page 48 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

Name GetLongLenth GetLowerBound GetType GetUpperBound GetValue IndexOf Intialize LastIndexOf ReferenceEquals Resize Reverse SetValue Sort ToString TrueForAll

Description Gets a 64-bit integer that represents the number of elements in the specified dimension of the Array. Gets the lower bound of the specified dimension in the Array. Gets the Type of the current instance. (Inherited from Object.) Gets the upper bound of the specified dimension in the Array. Overloaded. Gets the value of the specified element in the current Array. Overloaded. Returns the index of the first occurrence of a value in a one-dimensional Array or in a portion of the Array. Initializes every element of the value-type Array by calling the default constructor of the value type. Overloaded. Returns the index of the last occurrence of a value in a one-dimensional Array or in a portion of the Array. Overloaded. Returns the index of the last occurrence of a value in a one-dimensional Array or in a portion of the Array. Changes the size of an array to the specified new size. Overloaded. Reverses the order of the elements in a onedimensional Array or in a portion of the Array. Overloaded. Sets the specified element in the current Array to the specified value. Overloaded. Sorts the elements in one-dimensional Array objects. Returns a String that represents the current Object. (Inherited from Object.) Determines whether every element in the array matches the conditions defined by the specified predicate.

Protected Methods: S.No. 1 Name Finalize Description Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)

MemberwiseClone

Page 49 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 50 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 51 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 52 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 53 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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. 2. 3. 4. 5. 6. What are the types of arrays? What is jagged array and how do you declare it? What is method and how do you define it? What are the types of parameters? State the difference between parameter and parameter value. What do you mean by Method Overloading?

Page 54 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 55 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

The following are the members of the E-num class. Public Methods: S.No 1 2 3 Name CompareTo Equals Format Description Compares this instance to a specified object and returns an indication of their relative values. Overloaded. Overridden. Returns a value indicating whether this instance is equal to a specified object. Converts the specified value of a specified enumerated type to its equivalent string representation according to the specified format. Overridden. Returns the hash code for the value of this instance. Retrieves the name of the constant in the specified enumeration that has the specified value. Retrieves an array of the names of the constants in a specified enumeration. Gets the Type of the current instance. (Inherited from Object.) Returns the underlying TypeCode for this instance. Returns the underlying type of the specified enumeration. Retrieves an array of the values of the constants in a specified enumeration. Returns an indication whether a constant with a specified value exists in a specified enumeration. Overloaded. Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Overloaded. Returns an instance of the specified enumeration type set to the specified value. Overloaded. Overridden. Converts the value of this instance to its equivalent string representation.

4 5 6 7 8 9 10 11 12

GetHashcode GetName GetNames GetType GetTypeCode GetUnderlyingType GetValues IsDefined Parse

13 14 15

ReferenceEquals ToObject ToString

Protected Methods: S.No. 1 Name Finalize Description Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Creates a shallow copy of the current Object. (Inherited from Object.)

MemberwiseClone

Page 56 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 57 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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. 2. 3. 4. Why do you go for Enumeration? State the difference between structs and classes? What is called as a set of named constants? Are structs suitable only for a small data type?

Page 58 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 59 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 60 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 61 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 62 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 63 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 64 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 65 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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. 2. 3. 4. 5. Why do you need to go for OOPS? Differenciate between Object Oriented and Procedural Oriented programming. What are classes and objects? What is Inheritance? What is Polymorphism?

Page 66 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 Equals GetHashCode GetType Reference Equals ToString Means Indicates whether two Object instances are equal. Serves as a hash function for a particular type. Returns the Type of the current instance. Determines whether the specified Object instances are the same instance. 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 67 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 68 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 69 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 70 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 71 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

if (myData[i] == data) { myData[i] = value; } } } } //usage of OvrIndexer myInd[9] = myInd[3] = myInd[5] = an overloaded indexer myInd = new OvrIndexer(10); "Some Value"; "Another Value"; "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 72 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 public protected internal protected internal private Access is not restricted. Access is limited to the containing class or types derived from the containing class. Access is limited to the current assembly. Access is limited to the current assembly or types derived from the containing class. Access is limited to the containing type. Meaning

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 enum Default member accessibility public Allowed declared accessibility of the member None

Page 73 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Members class

Default member accessibility private

Allowed declared accessibility of the member public protected internal private protected internal None public internal private

interface struct

public 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 74 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 75 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 Classes Remarks The direct base class of a class type must be at least as accessible as the class type itself. The explicit base interfaces of an interface type must be at least as accessible as the interface type itself. The return type and parameter types of a delegate type must be at least as accessible as the delegate type itself. The type of a constant must be at least as accessible as the constant itself. The type of a field must be at least as accessible as the field itself. The return type and parameter types of a method must be at least as accessible as the method itself. The type of a property must be at least as accessible as the property itself. The type of an event must be at least as accessible as the event itself. The type and parameter types of an indexer must be at least as accessible as the indexer itself. The return type and parameter types of an operator must be at least as accessible as the operator itself. The parameter types of a constructor must be at least as accessible as the constructor itself.

Interfaces

Delegates

Constants Fields Methods

Properties Events Indexers

Operators

Constructors

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 76 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

// 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 77 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

} }

Summary
Following are the five types of access levels: o o o o o Public Protected Internal Protected internal 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. 2. 3. 4. State the differences between protected internal and internal access levels. Explain the usage of Internal Keyword. What are the accessors in properties? What are indexers?

Page 78 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 79 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 80 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

{ } } 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 81 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 82 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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. 2. 3. 4. What is the concept of partial class in .net 2.0? Why do you go for Partial classes? Define the scope of the static variables. Define the concept of Nested classes.

Page 83 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 84 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 inheritanceto 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 85 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 methodin 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 86 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

The syntax for defining an interface is very similar to the syntax for defining a class or a struct: [access-modifier ] interface interface-name body } [: base-list ] {interface-

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 87 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 inheritanceto 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. 2. 3. 4. 5. 6. What is inheritance? Does C# support multiple inheritances? What is the advantage of using inheritance? What is an abstract class? How do you achieve multiple inheritances in C#? Differenciate between abstract class and interfaces.

Page 88 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 89 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 90 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 91 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 92 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 93 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 94 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 95 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 96 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 97 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

{ /* ... */ } [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 98 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 99 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 mans 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 100 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Running From Within Visual Studio


The most convenient way to do this is to set up a custom tool entry specifying the path to NUnitgui.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 its 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 101 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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. 2. 3. 4. What are the different types of Assert? What is the syntax of Equality Assert? What is the use of TearDown method? How many TearDown methods can be declared in a program?

Page 102 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 103 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 where T: struct Description 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. The type argument must be a reference type, including any class, interface, delegate, or array type. The type argument must have a public parameterless constructor. When used in conjunction with other constraints, the new() constraint must be specified last. The type argument must be or derive from the specified base class. The type argument must be or implement the specified interface. Multiple interface constraints can be specified. The constraining interface can also be generic. The type argument supplied for T must be or derive from the argument supplied for U. This is called a naked type constraint.

where T : class where T : new()

where T : <base class name> where T : <interface name> where T : U

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 104 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 1 2 3 4 Class Dictionary List Queue Stack Description Represents a collection of keys and values. Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists. Represents a first-in, first-out collection of objects. 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 105 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

ICollection<KeyValuePair<TKey,TValue>>,IEnumerable<KeyValuePair <TKey,TValue>>, IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback Members: Public Properties: S.No 1 2 3 4 5 Name Comparer Count Item Keys Values Description Gets the IEqualityComparer that is used to determine equality of keys for the dictionary. Gets the number of key/value pairs contained in the Dictionary. Gets or sets the value associated with the specified key. Gets a collection containing the keys in the Dictionary. Gets a collection containing the values in the Dictionary.

Public Methods: S.No 1 2 3 4 5 6 7 Name Add Clear ContainsKey ContainsValue Equals GetEnumerator GetHashCode Description Adds the specified key and value to the dictionary. Removes all keys and values from the Dictionary. Determines whether the Dictionary contains the specified key. Determines whether the Dictionary contains a specific value. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) Returns an enumerator that iterates through the Dictionary. 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.) Implements the System.Runtime.Serialization.ISerializable interface and returns the data needed to serialize the Dictionary instance. Gets the Type of the current instance. (Inherited from Object.) Implements the System.Runtime.Serialization.ISerializable interface and raises the deserialization event when the deserialization is complete. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Removes the value with the specified key from the Dictionary. Returns a String that represents the current Object. (Inherited from Object.) Gets the value associated with the specified key.

GetObjectData

9 10

GetType OnDeserialization

11 12 13

ReferenceEquals Remove ToString

14

TryGetValue

Page 106 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Protected Methods: S.No 1 Name Finalize Description Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Creates a shallow copy of the current Object. (Inherited from Object.)

MemberwiseClone

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 1 2 3 Name Capacity Count Item Description Gets or sets the total number of elements the internal data structure can hold without resizing. Gets the number of elements actually contained in the List. Gets or sets the element at the specified index.

Public Methods: S.No 1 2 3 4 5 6 7 8 9 Name Add AddRange AsReadOnly BinarySearch Clear Contains ConvertAll CopyTo Equals Description Adds an object to the end of the List. Adds the elements of the specified collection to the end of the List. Returns a read-only IList wrapper for the current collection. Overloaded. Uses a binary search algorithm to locate a specific element in the sorted List or a portion of it. Removes all elements from the List. Determines whether an element is in the List. Converts the elements in the current List to another type, and returns a list containing the converted elements. Overloaded. Copies the List or a portion of it to an array. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

Page 107 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 10 11

Name Exists Find

Description Determines whether the List contains elements that match the conditions defined by the specified predicate. Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire List. Retrieves the all the elements that match the conditions defined by the specified predicate. Overloaded. Searches for an element that matches the conditions defined by a specified predicate, and returns the zerobased index of the first occurrence within the List or a portion of it. Searches for an element that matches the conditions defined by the specified predicate, and returns the last occurrence within the entire List. Overloaded. Searches for an element that matches the conditions defined by a specified predicate, and returns the zerobased index of the last occurrence within the List or a portion of it. Performs the specified action on each element of the List. Returns an enumerator that iterates through the List. 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.) Creates a shallow copy of a range of elements in the source List. Gets the Type of the current instance. (Inherited from Object.) Overloaded. Returns the zero-based index of the first occurrence of a value in the List or in a portion of it. Inserts an element into the List at the specified index. Inserts the elements of a collection into the List at the specified index. Overloaded. Returns the zero-based index of the last occurrence of a value in the List or in a portion of it. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Removes the first occurrence of a specific object from the List. Removes the all the elements that match the conditions defined by the specified predicate. Removes the element at the specified index of the List. Removes a range of elements from the List. Overloaded. Reverses the order of the elements in the List or a portion of it. Overloaded. Sorts the elements in the List or a portion of it.

12 13

FindAll FindIndex

14

FindLast

15

FindLastIndex

16 17 18

ForEach GetEnumerator GetHashCode

19 20 21 22 23 24 25 26 27 28 29 30 31

GetRange GetType IndexOf Insert InsertRange LastIndexOf ReferenceEquals Remove RemoveAll RemoveAt RemoveRange Reverse Sort

Page 108 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 32 33 34 35

Name ToArray ToString TrimExcess TrueForAll

Description Copies the elements of the List to a new array. Returns a String that represents the current Object. (Inherited from Object.) Sets the capacity to the actual number of elements in the List, if that number is less than a threshold value. Determines whether every element in the List matches the conditions defined by the specified predicate.

Protected Methods: S.No 1 Name Finalize Description Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Creates a shallow copy of the current Object. (Inherited from Object.)

MemberwiseClone

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 1 Name Count Description Gets the number of elements contained in the Queue.

Public Methods: S.No 1 2 3 4 5 6 Name Clear Contains CopyTo Dequeue Enqueue Equals Description Removes all objects from the Queue. Determines whether an element is in the Queue. Copies the Queue elements to an existing one-dimensional Array, starting at the specified array index. Removes and returns the object at the beginning of the Queue. Adds an object to the end of the Queue. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

Page 109 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 7 8

Name GetEnumerator GetHashCode

Description Returns an enumerator that iterates through the Queue. 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.) Gets the Type of the current instance. (Inherited from Object.) Returns the object at the beginning of the Queue without removing it. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Copies the Queue elements to a new array. Returns a String that represents the current Object. (Inherited from Object.) Sets the capacity to the actual number of elements in the Queue, if that number is less than 90 percent of current capacity.

9 10 11 12 13 14

GetType Peek ReferenceEquals ToArray ToString TrimExcess

Protected Methods: S.No 1 Name Finalize Description Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Creates a shallow copy of the current Object. (Inherited from Object.)

MemberwiseClone

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 1 Name Count Description Gets the number of elements contained in the Stack.

Page 110 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Public Methods: S.No 1 2 3 4 5 6 Name Clear Contains CopyTo Equals GetEnumerator GetHashCode Description Removes all objects from the Stack. Determines whether an element is in the Stack. Copies the Stack to an existing one-dimensional Array, starting at the specified array index. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) Returns an enumerator for the Stack. 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.) Gets the Type of the current instance. (Inherited from Object.) Returns the object at the top of the Stack without removing it. Removes and returns the object at the top of the Stack. Inserts an object at the top of the Stack. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Copies the Stack to a new array. Returns a String that represents the current Object. (Inherited from Object.) Sets the capacity to the actual number of elements in the Stack, if that number is less than 90 percent of current capacity.

7 8 9 10 11 12 13 14

GetType Peek Pop Push ReferenceEquals ToArray ToString TrimExcess

Protected Methods: S.No 1 Name Finalize Description Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Creates a shallow copy of the current Object. (Inherited from Object.)

MemberwiseClone

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 111 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Test Your Understanding


1. 2. 3. 4. 5. 6. 7. What is Generics? How do you define Generics? What are Constraints and how do you specify it? What is Naked Type constraints and where it is used? What is Generic method? How do you declare Generic method? What are the benefits of Generics?

Page 112 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 113 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 1 2 3 4 Class ArrayList Hashtable Queue Stack Description Implements the IList interface using an array whose size is dynamically increased as required. Represents a collection of key/value pairs that are organized based on the hash code of the key. Represents a first-in, first-out collection of objects. Represents a simple last-in-first-out (LIFO) non-generic collection of objects.

Page 114 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 1 2 3 4 5 6 7 Name Capacity Count IsFixedSize IsReadOnly IsSynchronized Item SyncRoot Description Gets or sets the number of elements that the ArrayList can contain. Gets the number of elements actually contained in the ArrayList. Gets a value indicating whether the ArrayList has a fixed size. Gets a value indicating whether the ArrayList is read-only. Gets a value indicating whether access to the ArrayList is synchronized (thread safe). Gets or sets the element at the specified index. Gets an object that can be used to synchronize access to the ArrayList.

Public methods: S.No 1 2 3 4 5 6 7 8 Name Adapter Add AddRange BinarySearch Clear Clone Contains CopyTo Description Creates an ArrayList wrapper for a specific IList. Adds an object to the end of the ArrayList. Adds the elements of an ICollection to the end of the ArrayList. Overloaded. Uses a binary search algorithm to locate a specific element in the sorted ArrayList or a portion of it. Removes all elements from the ArrayList. Creates a shallow copy of the ArrayList. Determines whether an element is in the ArrayList. Overloaded. Copies the ArrayList or a portion of it to a onedimensional array.

Page 115 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 9

Name Equals

Description Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) Overloaded. Returns a list wrapper with a fixed size, where elements are allowed to be modified, but not added or removed. Overloaded. Returns an enumerator that iterates through the ArrayList. 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.) Returns an ArrayList which represents a subset of the elements in the source ArrayList. Gets the Type of the current instance. (Inherited from Object.) Overloaded. Returns the zero-based index of the first occurrence of a value in the ArrayList or in a portion of it. Inserts an element into the ArrayList at the specified index. Inserts the elements of a collection into the ArrayList at the specified index. Overloaded. Returns the zero-based index of the last occurrence of a value in the ArrayList or in a portion of it. Overloaded. Returns a list wrapper that is read-only. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Removes the first occurrence of a specific object from the ArrayList. Removes the element at the specified index of the ArrayList. Removes a range of elements from the ArrayList. Returns an ArrayList whose elements are copies of the specified value. Overloaded. Reverses the order of the elements in the ArrayList or a portion of it. Copies the elements of a collection over a range of elements in the ArrayList.

10

FixedSize

11

GetEnumerator

12

GetHashCode

13

GetRange

14 15

GetType IndexOf

16 17

Insert InsertRange

18

LastIndexOf

19 20

ReadOnly ReferenceEquals

21

Remove

22 23 24

RemoveAt RemoveRange Repeat

25

Reverse

26

SetRange

Page 116 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 27 28

Name Sort Synchronized

Description Overloaded. Sorts the elements in the ArrayList or a portion of it. Overloaded. Returns a list wrapper that is synchronized (thread safe). Overloaded. Copies the elements of the ArrayList to a new array. Returns a String that represents the current Object. (Inherited from Object.) Sets the capacity to the actual number of elements in the ArrayList.

29 30

ToArray ToString

31

TrimToSize

Protected Methods S.No 1 Name Finalize Description Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Creates a shallow copy of the current Object. (Inherited from Object.)

MemberwiseClone

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 1 2 3 4 5 6 Name Count IsFixedSize IsReadOnly IsSynchronized Item Keys Description Gets the number of key/value pairs contained in the Hashtable. Gets a value indicating whether the Hashtable has a fixed size. Gets a value indicating whether the Hashtable is read-only. Gets a value indicating whether access to the Hashtable is synchronized (thread safe). Gets or sets the value associated with the specified key. Gets an ICollection containing the keys in the Hashtable.

Page 117 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 7 8

Name SyncRoot Values

Description Gets an object that can be used to synchronize access to the Hashtable. Gets an ICollection containing the values in the Hashtable.

Protected Properties: S.No 1 2 3 Name comparer EqualityComparer hcp Description Gets or sets the IComparer to use for the Hashtable. Gets the IEqualityComparer to use for the Hashtable. Gets or sets the object that can dispense hash codes.

Public methods: S.No 1 Name Add Description Adds an element with the specified key and value into the Hashtable. Removes all elements from the Hashtable. Creates a shallow copy of the Hashtable. Determines whether the Hashtable contains a specific key. Determines whether the Hashtable contains a specific key. Determines whether the Hashtable contains a specific value. Copies the Hashtable elements to a one-dimensional Array instance at the specified index. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) Returns an IDictionaryEnumerator that iterates through the Hashtable. 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.) Implements the ISerializable interface and returns the data needed to serialize the Hashtable. Gets the Type of the current instance. (Inherited from Object.) Implements the ISerializable interface and raises deserialization event when the deserialization is complete. the

2 3 4 5 6 7

Clear Clone Contains ContainsKey ContainsValue CopyTo

Equals

GetEnumerator

10

GetHashCode

11

GetObjectData

12 13

GetType OnDeserialization

Page 118 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 14

Name ReferenceEquals

Description Determines whether the specified Object instances are the same instance. (Inherited from Object.) Removes the element with the specified key from the Hashtable. Returns a synchronized (thread safe) wrapper for the Hashtable. Returns a String that represents the current Object. (Inherited from Object.)

15 16 17

Remove Synchronized ToString

Protected Methods: S.No 1 Name Finalize Description Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Returns the hash code for the specified key. Compares a specific Object with a specific key in the Hashtable. Creates a shallow copy of the current Object. (Inherited from Object.)

2 3 4

GetHash KeyEquals MemberwiseClone

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 1 2 3 Name Count IsSynchronized SyncRoot Description Gets the number of elements contained in the Queue. Gets a value indicating whether access to the Queue is synchronized (thread safe). Gets an object that can be used to synchronize access to the Queue.

Page 119 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Public Methods: S.No 1 2 3 4 5 6 7 8 9 Name Clear Clone Contains CopyTo Description Removes all objects from the Queue. Creates a shallow copy of the Queue. Determines whether an element is in the Queue. Copies the Queue elements to an existing one-dimensional Array, starting at the specified array index. Removes and returns the object at the beginning of the Queue. Adds an object to the end of the Queue. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) Returns an enumerator that iterates through the Queue. 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.) Gets the Type of the current instance. (Inherited from Object.) Returns the object at the beginning of the Queue without removing it. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Returns a Queue wrapper that is synchronized (thread safe). Copies the Queue elements to a new array. Returns a String that represents the current Object. (Inherited from Object.) Sets the capacity to the actual number of elements in the Queue.

Dequeue Enqueue Equals

GetEnumerator GetHashCode

10 11 12 13 14 15 16

GetType Peek

ReferenceEquals

Synchronized ToArray ToString

TrimToSize

Protected methods: S.No 1 Name Finalize Description Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Creates a shallow copy of the current Object. (Inherited from Object.)

MemberwiseClone

Page 120 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 1 2 3 Name Count IsSynchronized SyncRoot Description Gets the number of elements contained in the Stack. Gets a value indicating whether access to the Stack is synchronized (thread safe). Gets an object that can be used to synchronize access to the Stack.

Public methods: S.No 1 2 3 4 5 6 7 Name Clear Clone Contains CopyTo Equals GetEnumerator GetHashCode Description Removes all objects from the Stack. Creates a shallow copy of the Stack. Determines whether an element is in the Stack. Copies the Stack to an existing one-dimensional Array, starting at the specified array index. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) Returns an IEnumerator for the Stack. 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.) Gets the Type of the current instance. (Inherited from Object.) Returns the object at the top of the Stack without removing it. Removes and returns the object at the top of the Stack. Inserts an object at the top of the Stack. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Returns a synchronized (thread safe) wrapper for the Stack. Copies the Stack to a new array. Returns a String that represents the current Object. (Inherited from Object.)

8 9 10 11 12 13 14 15

GetType Peek Pop Push ReferenceEquals Synchronized ToArray ToString

Page 121 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Protected methods: S.No 1 Name Finalize Description Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Creates a shallow copy of the current Object. (Inherited from Object.)

MemberwiseClone

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. 2. 3. 4. 5. 6. 7. What are collections? What are the namespaces used for collections? What are the types of collections used? Distinguish between dictionary and sorted dictionary. What is the functionality of stack? Sate the difference between stack and a queue. What are the methods used in HashTable?

Page 122 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 123 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

} 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 124 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 125 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 1 Name ExceptionCollection Description Initializes a new instance of the ExceptionCollection class.

Public Properties: S.No 1 2 3 4 Name Data Exceptions HelpLink InnerException Description Gets a collection of key/value pairs that provide additional, userdefined information about the exception.(Inherited from Exception.) Gets the array of Exception objects that represent the collection of exceptions. Gets or sets a link to the help file associated with this exception.(Inherited from Exception.) Gets the Exception instance that caused the current exception.(Inherited from Exception.)

Page 126 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 5 6 7 8

Name Message Source StackTrace TargetSite

Description Gets a message that describes the current exception.(Inherited from Exception.) Gets or sets the name of the application or the object that causes the error.(Inherited from Exception.) Gets a string representation of the frames on the call stack at the time the current exception was thrown.(Inherited from Exception.) Gets the method that throws the current exception.(Inherited from Exception.)

Protected Properties S.No 1 Name HResult Description Gets or sets HRESULT, a coded numerical value that is assigned to a specific exception. (Inherited from Exception.)

Public Methods S.No 1 2 Name Equals GetBaseException Description Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) When overridden in a derived class, returns the Exception that is the root cause of one or more subsequent exceptions. (Inherited from Exception.) 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.) Overridden. Populates a SerializationInfo with the data needed to serialize the ExceptionCollection. Gets the runtime type of the current instance. (Inherited from Exception.) Determines whether the specified Object instances are the same instance. (Inherited from Object.) Creates and returns a string representation of the current exception. (Inherited from Exception.)

GetHashCode

4 5 6 7

GetObjectData GetType Reference Equals ToString

Protected Methods: S.No 1 Name Finalize Description Allows an Object to attempt to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) Creates a shallow copy of the current Object. (Inherited from Object.)

MemberwiseClone

Page 127 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 o SystemExceptions: The CLR generates SystemExceptions, which can occur at any point during program execution ApplicationException: It is a base class that programmers can extend to create exception classes that are specific to their applications

Page 128 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Test your Understanding


1. 2. 3. 4. 5. What do you understand by Exception class? State some features about Exception properties. Differentiate between System Exceptions and User defined Exceptions. Describe some system exceptions. Give program samples for using multiple exceptions with throw and finally statements.

Page 129 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 1 2 3 4 5 6 7 8 Name CanRead CanSeek CanTimeout CanWrite Length Position ReadTimeout WriteTimeout Description When overridden in a derived class, gets a value indicating whether the current stream supports reading. When overridden in a derived class, gets a value indicating whether the current stream supports seeking. Gets a value that determines whether the current stream can time out. When overridden in a derived class, gets a value indicating whether the current stream supports writing. When overridden in a derived class, gets the length in bytes of the stream. When overridden in a derived class, gets or sets the position within the current stream. Gets or sets a value that determines how long the stream will attempt to read before timing out. Gets or sets a value that determines how long the stream will attempt to write before timing out.

Page 130 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Public Methods: S.No 1 2 3 Name BeginRead BeginWrite Close Description Begins an asynchronous read operation. Begins an asynchronous write operation. Closes the current stream and releases any resources (such as sockets and file handles) associated with the current stream. Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object. (Inherited from MarshalByRefObject.) Overloaded. Releases all resources used by the Stream object. Waits for the pending asynchronous read to complete. Ends an asynchronous write operation. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) When overridden in a derived class, clears all buffers for this stream and causes any buffered data to be written to the underlying device. 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.) Retrieves the current lifetime service object that controls the lifetime policy for this instance. (Inherited from MarshalByRefObject.) Gets the Type of the current instance. (Inherited from Object.) Obtains a lifetime service object to control the lifetime policy for this instance. (Inherited from MarshalByRefObject.) 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. 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. Determines whether the specified Object instances are the same instance. (Inherited from Object.) When overridden in a derived class, sets the position within the current stream.

CreateObjRef

5 6 7 8 9

Dispose EndRead EndWrite Equals Flush

10

GetHashCode

11

GetLifetimeService

12 13

GetType InitializeLifetimeService

14

Read

15

ReadByte

16 17

ReferenceEquals Seek

Page 131 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 18 19 20 21

Name SetLength Synchronized ToString Write

Description When overridden in a derived class, sets the length of the current stream. Creates a thread-safe (synchronized) wrapper around the specified Stream object. Returns a String that represents the current Object. (Inherited from Object.) 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. Writes a byte to the current position in the stream and advances the position within the stream by one byte.

22

WriteByte

Binary Reader
Reads primitive data types as binary values in a specific encoding. Public properties: S.No 1 Name BaseStream Description Exposes access to the underlying stream of the BinaryReader.

Public Methods: S.No 1 2 3 Name Close Equals GetHashCode Description Closes the current reader and the underlying stream. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) 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.) Gets the Type of the current instance. (Inherited from Object.) Returns the next available character and does not advance the byte or character position. Overloaded. Reads characters from the underlying stream and advances the current position of the stream. Reads a Boolean value from the current stream and advances the current position of the stream by one byte. Reads the next byte from the current stream and advances the current position of the stream by one byte. Reads count bytes from the current stream into a byte array and advances the current position by count bytes.

4 5 6 7 8 9

GetType PeekChar Read ReadBoolean ReadByte ReadBytes

Page 132 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 10

Name ReadChar

Description 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. 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. Reads a decimal value from the current stream and advances the current position of the stream by sixteen bytes. Reads an 8-byte floating point value from the current stream and advances the current position of the stream by eight bytes. Reads a 2-byte signed integer from the current stream and advances the current position of the stream by two bytes. Reads a 4-byte signed integer from the current stream and advances the current position of the stream by four bytes. Reads an 8-byte signed integer from the current stream and advances the current position of the stream by eight bytes. Reads a signed byte from this stream and advances the current position of the stream by one byte. Reads a 4-byte floating point value from the current stream and advances the current position of the stream by four bytes. Reads a string from the current stream. The string is prefixed with the length, encoded as an integer seven bits at a time. Reads a 2-byte unsigned integer from the current stream using little endian encoding and advances the position of the stream by two bytes. Reads a 4-byte unsigned integer from the current stream and advances the position of the stream by four bytes. Reads an 8-byte unsigned integer from the current stream and advances the position of the stream by eight bytes. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Returns a String that represents the current Object. (Inherited from Object.)

11

ReadChars

12 13 14 15 16 17 18 19 20

ReadDecimal ReadDouble ReadInt16 ReadInt32 ReadInt64 ReadSByte ReadSingle ReadString ReadUInt16

21 22 23 24

ReadUInt32 ReadUInt64 ReferenceEquals ToString

Binary Writer
Writes primitive types in binary to a stream and supports writing strings in a specific encoding. Public Fields: S.No 1 Name Null Description Specifies a BinaryWriter with no backing store.

Page 133 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Public Properties: S.No 1 Name BaseStream Description Gets the underlying stream of the BinaryWriter.

Public Methods: S.No 1 2 3 4 Name Close Equals Flush GetHashCode Description Closes the current BinaryWriter and the underlying stream. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) Clears all buffers for the current writer and causes any buffered data to be written to the underlying device. 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.) Gets the Type of the current instance. (Inherited from Object.) Determines whether the specified Object instances are the same instance. (Inherited from Object.) Sets the position within the current stream. Returns a String that represents the current Object. (Inherited from Object.) Overloaded. Writes a value to the current stream.

5 6 7 8 9

GetType ReferenceEquals Seek ToString Write

Text Reader
Represents a reader that can read a sequential series of characters. Public fields: S.No 1 Name Null Description Provides a TextReader with no data to read from.

Public Methods: S.No 1 2 Name Close CreateObjRef Description Closes the TextReader and releases any system resources associated with the TextReader. Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object. (Inherited from MarshalByRefObject.) Overloaded. Releases all resources used by the TextReader object. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.)

3 4

Dispose Equals

Page 134 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 5

Name GetHashCode

Description 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.) Retrieves the current lifetime service object that controls the lifetime policy for this instance. (Inherited from MarshalByRefObject.) Gets the Type of the current instance. (Inherited from Object.) Obtains a lifetime service object to control the lifetime policy for this instance. (Inherited from MarshalByRefObject.) 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. Overloaded. Reads data from an input stream. Reads a maximum of count characters from the current stream and writes the data to buffer, beginning at index. Reads a line of characters from the current stream and returns the data as a string. Reads all characters from the current position to the end of the TextReader and returns them as one string. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Creates a thread-safe wrapper around the specified TextReader. Returns a String that represents the current Object. (Inherited from Object.)

GetLifetimeService

7 8

GetType InitializeLifetimeService

Peek

10 11

Read ReadBlock

12 13

ReadLine ReadToEnd

14 15 16

ReferenceEquals Synchronized ToString

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 135 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

{ 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 1 Name Null Description Provides a TextWriter with no backing store that can be written to, but not read from.

Public Properties: S.No 1 2 3 Name Encoding FormatProvider NewLine Description When overridden in a derived class, returns the Encoding in which the output is written. Gets an object that controls formatting. Gets or sets the line terminator string used by the current TextWriter.

Page 136 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Public Methods: S.No 1 2 Name Close CreateObjRef Description Closes the current writer and releases any system resources associated with the writer. Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object. (Inherited from MarshalByRefObject.) Overloaded. Releases all resources used by the TextWriter object. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) Clears all buffers for the current writer and causes any buffered data to be written to the underlying device. 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.) Retrieves the current lifetime service object that controls the lifetime policy for this instance. (Inherited from MarshalByRefObject.) Gets the Type of the current instance. (Inherited from Object.) Obtains a lifetime service object to control the lifetime policy for this instance. (Inherited from MarshalByRefObject.) Determines whether the specified Object instances are the same instance. (Inherited from Object.) Creates a thread-safe wrapper around the specified TextWriter. Returns a String that represents the current Object. (Inherited from Object.) Overloaded. Writes the given data type to a text stream. Overloaded. Writes some data as specified by the overloaded parameters, followed by a line terminator.

3 4 5

Dispose Equals Flush

GetHashCode

GetLifetimeService

8 9

GetType InitializeLifetimeService

10 11 12 13 14

ReferenceEquals Synchronized ToString Write WriteLine

Page 137 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 138 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 1 Name Null Description A StreamReader object around an empty stream.

Public properties: S.No 1 2 3 Name BaseStream CurrentEncoding EndOfStream Description Returns the underlying stream. Gets the current character encoding that the current StreamReader object is using. Gets a value that indicates whether the current stream position is at the end of the stream.

Public Methods: S.No 1 Name Close Description Overridden. Closes the StreamReader object and the underlying stream, and releases any system resources associated with the reader. Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object. (Inherited from MarshalByRefObject.) Allows a StreamReader object to discard its current data. Overloaded. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) 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.)

CreateObjRef

3 4 5 6

DiscardBufferedData Dispose Equals GetHashCode

Page 139 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 7

Name GetLifetimeService

Description Retrieves the current lifetime service object that controls the lifetime policy for this instance. (Inherited from MarshalByRefObject.) Gets the Type of the current instance. (Inherited from Object.) Obtains a lifetime service object to control the lifetime policy for this instance. (Inherited from MarshalByRefObject.) Overridden. Returns the next available character but does not consume it. Overloaded. Overridden. Reads the next character or next set of characters from the input stream. Reads a maximum of count characters from the current stream and writes the data to buffer, beginning at index. (Inherited from TextReader.) Overridden. Reads a line of characters from the current stream and returns the data as a string. Overridden. Reads the stream from the current position to the end of the stream. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Creates a thread-safe wrapper around the specified TextReader. (Inherited from TextReader.) Returns a String that represents the current Object. (Inherited from Object.)

8 9

GetType InitializeLifetimeService

10 11 12

Peek Read ReadBlock

13 14 15 16 17

ReadLine ReadToEnd ReferenceEquals Synchronized ToString

Stream Writer Class


Implements a TextWriter for writing characters to a stream in a particular encoding. Public fields: S.No 1 Name Null Description Provides a StreamWriter with no backing store that can be written to, but not read from.

Public properties: S.No 1 Name AutoFlush Description Gets or sets a value indicating whether the StreamWriter will flush its buffer to the underlying stream after every call to StreamWriter.Write. Gets the underlying stream that interfaces with a backing store. Overridden. Gets the Encoding in which the output is written.

2 3

BaseStream Encoding

Page 140 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

S.No 4 5

Name FormatProvider NewLine

Description Gets an object that controls formatting.(Inherited from TextWriter.) Gets or sets the line terminator string used by the current TextWriter.(Inherited from TextWriter.)

Public Methods: S.No 1 2 Name Close CreateObjRef Description Overridden. Closes the current StreamWriter object and the underlying stream. Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object. (Inherited from MarshalByRefObject.) Overloaded. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) Overridden. Clears all buffers for the current writer and causes any buffered data to be written to the underlying stream. 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.) Retrieves the current lifetime service object that controls the lifetime policy for this instance. (Inherited from MarshalByRefObject.) Gets the Type of the current instance. (Inherited from Object.) Obtains a lifetime service object to control the lifetime policy for this instance. (Inherited from MarshalByRefObject.) Determines whether the specified Object instances are the same instance. (Inherited from Object.) Creates a thread-safe wrapper around the specified TextWriter. (Inherited from TextWriter.) Returns a String that represents the current Object. (Inherited from Object.) Overloaded. Writes to the stream. Overloaded. Writes some data as specified by the overloaded parameters, followed by a line terminator. (Inherited from TextWriter.)

3 4 5

Dispose Equals Flush

GetHashCode

GetLifetimeService

8 9

GetType InitializeLifetimeService

10 11 12 13 14

ReferenceEquals Synchronized ToString Write WriteLine

Page 141 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 142 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 143 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 144 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 145 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 146 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 147 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 148 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 IsStartElement ReadStartElement

Description Checks if the current node is a start tag or an empty element tag. Checks that the current node is an element and advances the reader to the next node.

Page 149 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Member name ReadEndElement

Description 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. Advances the XmlReader to the next sibling element with the specified name. 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.

ReadToNextSibling

IsEmptyElement

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-xml20001006.html) recommendation and the Namespaces in XML recommendation (www.w3.org/TR/REC-xml-names/).

Page 150 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 WriteAttributeString

Description of work done XmlTextWriter escapes the text content of the attribute depending on what it finds. XmlTextWriter escapes special characters, replacing them with &amp; &lt; &gt; and numeric character entities when required. XmlTextWriter encodes the base64 bytes, which can then be read using ReadBinary on the XmlReader.

WriteString

WriteBase64

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 151 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

<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. 2. 3. 4. What are the namespaces used for XML in .Net framework? What is the purpose of XMLTextReader? What is the purpose of XMLTextWriter? What are the design goals of XML?

Page 152 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 153 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 154 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 155 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

// 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 156 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

{ 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 157 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 158 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

{ 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 159 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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. 2. 3. 4. What is an Event? What is a Delegate? What is EventWiring? What is an EventHandler?

Page 160 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 threads 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 161 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 Suns Java and Microsofts .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 162 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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. Lets 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 163 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

} } } 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 o Processes are fully isolated from each other. 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 164 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 165 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 datathat is, information about the types, code, assembly, and so forththat 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 166 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 167 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 168 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

// 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 169 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 170 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 171 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 172 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

{ 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 173 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. What is Serialization? What is Deserialization? What are the Types of serialization? What is a Binary Serialization? What are the advantages and disadvantages of using Binary Serialization? What is Soap Serialization? What is XML Serialization? What is Custom Serialization? What is Binary Formatter? What is Soap Formatter? What are the advantages and disadvantages of Serialization?

Page 174 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 175 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 Garbage Collector to manage memory Type Standard objects Objects are created by normal new operator Exceptions will be returned Object info resides in assembly files Interface based communication Reference count will be used to manage memory Binary Standard objects Objects are created by coCreateInstance HRESULT will be returned 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 176 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

.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 177 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 codes 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 o Interop marshalling 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 178 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Test your Understanding


1. 2. 3. 4. 5. 6. 7. What is interoperability? What is unmanaged code with examples? Differentiate between managed code and unmanaged code? What is RCW? Differentiate between RCW and CCW? What is marshalling? What are the types of marshalling?

Page 179 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 180 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 181 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

</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 182 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 183 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 184 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Test your Understanding


1. 2. 3. 4. 5. 6. What is Remoting? What is the advantage of using remoting? What is Application Domain? Describe channels and proxy? What are the basic rules which are applicable for Remoting? What are the object modes for server activation?

Page 185 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 186 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 187 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 188 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

{ 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 189 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 wellknown 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. 2. 3. 4. How do you make an object remotable? What is the formatting type used by HTTP channel? What is the formatting type used by TCP channel? What is the namespace used for Remoting?

Page 190 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 191 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 192 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 193 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 194 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 195 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

{ // 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 196 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

{ 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 197 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

} } 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 198 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 AddMemoryPressure Description Informs the runtime of a large allocation of unmanaged memory that should be taken into account when scheduling garbage collection. Overloaded. Forces garbage collection. Returns the number of times garbage collection has occurred for the specified generation of objects. Overloaded. Determines whether two Object instances are equal. (Inherited from Object.) Overloaded. Returns the current generation number of an object. 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.) 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. Gets the Type of the current instance. (Inherited from Object.) 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. Determines whether the specified Object instances are the same instance. (Inherited from Object.) Informs the runtime that unmanaged memory has been released and no longer needs to be taken into account when scheduling garbage collection.

Collect CollectionCount

Equals

GetGeneration GetHashCode

GetTotalMemory

GetType KeepAlive

ReferenceEquals

RemoveMemoryPressure

ReRegisterForFinalize Requests that the system call the finalizer for the specified object, for which SuppressFinalize has previously been called.

Page 199 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

Name SuppressFinalize

Description Requests that the system not call the finalizer for the specified object. Returns a String that represents the current Object. (Inherited from Object.)

ToString

WaitForPendingFinaliz Suspends the current thread until the thread processing the queue ers 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. 2. 3. 4. Which object implements Garbage Collection in .Net? Which method forces Garbage collection? How many generations are available in .Net? Where are objects created in the memory? a) Stack b) Heap 5. Which statement implements Dispose functionality automatically in C#?

Page 200 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 201 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 ObjectOriented 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 componentbased 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 202 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 203 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 204 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 205 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 JustIn-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 206 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

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 207 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

References

Websites
Visual C# Developer Center: o o http://msdn.microsoft.com/vcsharp/ http://msdn.microsoft.com/netframework/ .NET Framework Developer Center 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 208 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Handout - C#

STUDENT NOTES:

Page 209 Copyright 2007, Cognizant Technology Solutions, All Rights Reserved C3: Protected

Das könnte Ihnen auch gefallen