Você está na página 1de 233

C# Programming and

.NET Concepts

By
Satish B Basapur
E-mail: satish.basapur@yahoo.com

1
Books for Reference
 C# and the .NET Platform (2 Ed)
 By Andrew Troelsen
 Dreamtech Publications
 Microsoft Visual C# .NET
 By Mickey Williams
 Microsoft Press

2
Chapter - 1

The Philosophy of .NET

3
Objectives
 Understanding the previous state of affairs
 The .NET Solution
 Building blocks of .NET Platform
 CLR, CTS, and CLS
 .NET Base Class Libraries

4
Understanding the
previous state of affairs
 As a C/Win32 API Programmer
 It is complex
 C is a short/abrupt language
 Manual memory management, ugly pointer arithmetic, ugly syntactic
constructs
 Not a OO language
 As a C++/MFC Programmer
 Root is C
 C++ with MFC is still complex and error-prone
 As a VB 6 Programmer
 Not a complete OOP (“Object-aware”) – Why?
 Doesn’t support inheritance
 No multithreading
 No parameterized Classes
 Low-level API calls are complex
5
Previous state of affairs…
 As a Java/J2EE Programmer
 Use of Java front-to-back during development cycle
 No language freedom!
 Pure Java is not suitable for graphic intensive problems (E.g. 3D
game)
 No cross-language integration
 As a COM Programmer
 Complex creation of COM types
 Active Template Library (ATL)
 Forced to contend with brittle/fragile registration entries
 Deployment issues

6
.NET Solution
 Full interoperability with existing Win32 Code
 Existing COM binaries can interoperate with .NET binaries
 Complete and total language integration
 Supports cross-language inheritance, exception handling, and debugging
 Common runtime engine shared by all .NET aware languages
 A base class library
 Good object model used by all .NET aware languages
 No more COM plumbing!
 No IClassFactory, IUnKnown, IDispatch, etc.
 Truly simplified deployment model
 No need to register a binary unit into the system registry
 Allows multiple versions of same *.dll

7
.NET Framework
VB C++ C# JScript J#

Common Language Specification

Visual Studio.NET
ASP.NET Windows
Web Forms Web Services Forms

ADO.NET and XML

Base Class Library

Common Language Runtime

Operating System

8
Building Blocks of .NET
 CLR (Common Language Runtime)
 To locate, load, and manage .NET types
 Automatic memory management, language integration, and type
safety
 CTS (Common Type System)
 Describes all possible data types and programming constructs
supported by the runtime
 CLS (Common Language Specification)
 A set of rules that defines a subset of types and specifications

9
CLR (Common Language Runtime)
 CLR sits on top of OS (same as JVM of Java)
 CLR loads modules containing executables and executes them
 Code may be managed or unmanaged
 Managed code consists of instructions in pseudo random code called CIL (Common
Intermediate Language). CIL instructions are JIT compiled into native machine
code at runtime
 JIT compiled methods reside in cache until the application’s life time
 Advantages of managed code: type safety, memory management, and code
verification security
 CLR can translate code from C#, J#, C, C++, VB, and Jscript into CIL.
 CLR doesn’t launch a new process for every application. It launches one process
and hosts individual applications in application domains

10
Base Class Libraries
 Encapsulates various primitives like: threads, file IO, graphical
rendering, and other interaction with HW devices
 It also provides: database manipulation, XML integration, Web-enabled
front-end.

Data Access GUI Base Class Libraries

Threading File IO XML/SOAP

Common Language Runtime

CTS CLS
11
C#
 Almost same as Java
 No pointers required
 Automatic memory management (No ‘delete’)
 Enumeration, class, structure, etc.
 Operator overloading allowed
 Interface-based programming techniques
 Assign characteristics to types (same as COM IDL)
 C# can produce code that can run only on .NET environment
(unlike COM server or Win32 API)

12
Understanding Assemblies
 Windows applications have dependencies on one or more
DLLs
 These DLLs may contain COM classes registered in System
registry
 When these components are updated, applications may
break – 'DLL hell'
 Solution: .NET Assemblies
 C# .NET compiler doesn't generate machine code.
 It is compiled into "assembly"

13
Assembly
Metadata

IL
C# source code + C# .NET Compiler =
Assembly
 Intermediate Language (IL/CIL):
 Same as first pass of compiler. It can't be executed (it is not in binary
format)
 Metadata
 Describes the assembly contents
 No need for component registry
 Each assembly includes information about references to other assemblies
 E.g. If you have a class called Car in a given assembly, the type metadata
describes Car's base class, which interfaces are implemented by Car,
description of members of Car.

14
Assembly…
 When CLR loads your application, it examines your program's metadata to
know which external assemblies are required for execution
 Private assemblies
 Used by single application
 Is not shared
 Most preferred method
 Shared assemblies
 Intended for multiple applications
 Global Assembly Cache
 Manifest
 The metadata of assemblies: version, list of externally defined assemblies,
etc.

15
Example of CIL
 CIL sits above a specific compiler (C#, J#, etc.) public class Calc
 The associated compiler emits CIL instructions {
public int Add(int x, int y)
using System; { return x + y; }
namespace Calculator }
{ }

public class CalcApp


{

public static void Main(string[] args)


 All .NET aware languages
{ emit same CIL instructions
Calc c = new Calc();
int ans = c.Add(10, 84);
Console.WriteLine(ans);
Console.ReadLine();
}
}

16
CIL of Add() Method
.method public hidebysig instance int32 Add(int32 x,
int32 y) cil managed
{
// Code size 8 (0x8)
.maxstack 2
.locals init ([0] int32 CS$00000003$00000000)
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: add
IL_0003: stloc.0
IL_0004: br.s IL_0006
IL_0006: ldloc.0
IL_0007: ret
} // end of method Calc::Add

17
External
Manifest Assembly

.assembly extern mscorlib


{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 1:0:5000:0
}
.assembly ConsoleApplication1
{

.hash algorithm 0x00008004


.ver 1:0:2058:39833
}
.module ConsoleApplication1.exe
// MVID: {51BE4F31-CBD0-4AE6-BC9D-F9A4976795FD}
.imagebase 0x00400000
.subsystem 0x00000003
.file alignment 4096
.corflags 0x00000001
// Image base: 0x070b0000

18
CIL to Execution
Desktop

CIL JIT Server

Pocket PC

 Jitter compiles CIL instructions on the fly into corresponding


machine code and cache it. This is useful for not recompiling,
if the same method is called again

19
Common Type System (CTS)
 CTS is a formal specification that describes how a
given type must be defined for CLR
 CTS Class Type
 CTS Structure Type
 CTS Interface Type
 CTS Enumeration type
 CTS Delegate type

20
CTS Class Type
 Same as C++ class
 Can contain members: methods, properties, events,
etc.
 Support for abstract members that define a
polymorphic interface for derived classes
 Multiple inheritance is not allowed

21
CTS Class Characteristics
 "sealed"? – sealed classes can't function as base classes
 Implement any interfaces? – An interface is a collection of
abstract members
 Abstract or Concrete? – Abstract classes (to define common
behaviors for derived) can't be created directly but concrete
classes can.
 Visibility? – visibility attribute to know whether external
assemblies can use it.

22
 CTS Structure types
 Same as C/C++
 Derived from a common base class System.ValueType
 CTS Interface Type
 Same as pure abstract class of C++
 A description of work that a derived class can perform
 Similar to a class, but can never be instantiated
 CTS Enumeration type
 To group name/value pairs under a specific name
 Default Storage: System.Int32 (could be changed)
 CTS Delegate type
 Same as C's function pointer (System.MulticastDelegate)
 Useful for event handling (ASP .NET)

23
Intrinsic CTS Data Types
.NET Base Type C# Type
System.Byte Byte
System.SByte sbyte
System.Int16 short
System.Int32 int
System.Int64 long
System.UInt64 ulong
System.Single float
System.Double double
System.Object object
System.String string
System.Boolean bool
24
Common Language Specification
(CLS)
 Set of guidelines that describe the minimal and complete set
of features a given .NET aware compiler must support
 C# uses + for concatenation whereas VB .NET uses &
 C# allows operator overloading but VB .NET does not!
 The void functions may differ in syntax:
' VB .NET // C#
Public Sub Foo() public void Foo()
'……. { ……. }
End Sub

25
CLS Compliance
C# Type CLS Compliance
byte Yes
sbyte No
short Yes
int Yes
long Yes
ulong No
float Yes
double Yes
object Yes
string Yes
char Yes
bool Yes 26
Example
public class Calc
{
// CLS compliant
public int Add(int x, int y)
{ return x + y; }

// Not CLS compliant


public ulong Add(ulong x, ulong y)
{ return x + y; }
}
 Once a method is CLS compliant, then all the .NET aware languages
can interact with that implementation

27
CLR .NET .NET Compiler
Source
Code
DLL or EXE
(CIL)

mscoree.dll

Class Loader

Base Class
Libraries Jitter
(mscorlib.dll)

Platform
Specific code

mscoree.dll
Execute
MicroSoft Common
Object Runtime Execution Engine .NET Execution Engine
28
.NET Namespace
 MFC, Java, VB 6.0 have predefined set of classes;
C# doesn't
 C# uses namespace concept
 Any language targeting the .NET runtime makes use
of the same namespaces and same types as C#
 System is the root namespace

29
System Namespace
Example in C#
using System;
public Class MyApp
{
public static void Main() Console class in
System Namespace
{
Console.WriteLine("Hello World");
}
}

30
Example in VB .NET
Imports System
Public Module MyApp
Sub Main()
Console.WriteLine("Hello World")
End Sub
End Module

31
Example in Managed C++
#using <mscorlib.dll>
using namespace System;
void Main()
{
Console::WriteLine("Hello World");
}

32
Sample .NET namespaces
System primitive types, garbage collection, etc

System.Collections Container objects: ArrayList, Queue, etc.

System.Data For Database manipulations ADO .NET


System.Data.Common
System.Data.OleDb
System.Data.SqlClient
System.IO file IO, buffering, etc.
System.Drawing GDI+ primitives, bitmaps, fonts, icons, etc.
System.Drawing.2D
System.Threading Threads

33
Demo

 Console Application
 Windows Application
 Graphics

34
End of Chapter 1

35
36
Chapter 2

Building C# Applications

37
Objectives
 Command Line Compilation
 Visual Studio .NET IDE
 Referencing External Assemblies
 Demo – Multi Language

38
Configuration for csc
 Right Click My Computer  Properties  Advanced
Environment variables  Double Click Path

 Add the path where csc.exe is loaded


 C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322

39
Command Line Compilation
 Compiling single source file
csc /target:exe TestApp.cs or
csc TestApp.cs
 csc C Sharp Compiler
 /target:exe *.exe console application
 /target:winexe windows application
 /out to name the output File

 Compiling multiple source files


csc /r:System.Windows.Forms.dll TestApp.cs Hello.cs 40
Example (Console based)
// Hello.cs
using System;
public class Hello
{
public static void Main(String[ ] args)
{
Console.WriteLine("Hello World");
}
}
41
Example (Windows based)
// HelloWin.cs
using System;
using System.Windows.Forms;
public class HelloWin
{
public static void Main(String[ ] args)
{
Console.WriteLine("Hello World");
MessageBox.Show("Hi, I am now in Windows!");
}
}
42
Compiling Multiple Source Files
// Car.cs // HelloDriver.cs
using System; using System;
public class HelloDriver
public class Car
{
{
public static void Main
public void Display() (String[ ] args)
{ {
MessageBox.Show Console.WriteLine
("Car Class"); ("Hello World");
} Car c = new Car();
} c.Display();
}
}

43
csc /r:System.Windows.Forms.dll HelloDriver.cs Car.cs
Visual Studio .NET IDE
 .NET Start Page

44
.NET Project Window

45
Project Types
Windows Application Windows Forms
Class Library Builds single file assembly (*.dll)

Windows Control Library Same as ActiveX Control


ASP .NET Web Application Builds ASP .NET Web
Application
ASP .NET Web Service .NET Web Service
Web Control Library Customized Web Controls
Console Application Old Console based
Windows Services NT/2000 services (background worker
applications)
46
.NET Main Page
Solution
Tool Explorer
Box View

Class
View

47
Configuring a C# Project

48
Referencing External Assemblies
 These are predefined list of assemblies automatically
recognized by .NET

49
Other features of .NET IDE
 Debugging
 Breakpoints
 XML – Related Editing Tools
 Object Browser
 Help Menu (F1 is your friend)
 Documenting the Source Code (XML)
 C# Preprocessor Directives

50
Web Sites for Other IDEs
 www.gotdotnet.com
 www.icsharpcode.net

51
52
Chapter 3

C# Language Fundamentals

53
OBJECTIVES
 Basic C# Class
 Constructors
 Basic Input and Output
 Value Types and Reference Types
 Iteration Statements
 Control Flow Statements
 Static Methods and Parameter passing Methods
 Arrays, Strings, and String Manipulations
 Enumerations and Structures
54
Basic C# Class
// Hello.cs The using keyword has two major uses:
using Directive   Creates an alias for a namespace
using System; or imports types defined in other namespaces.
class HelloClass using Statement   Defines a scope at the end of
{ which an object will be disposed.
public static int Main(string[ ] args)
{
Console.WriteLine("Hello World");
return 0;
}
}

55
Basic C# Class - Variations
// Hello1.cs // Hello2.cs
using System; using System;
class HelloClass class HelloClass
{ {
public static void Main()
public static void Main(string[ ] args)
{
{
// ………….
// ………. }
} }
}

56
Command Line Parameters
// clp.cs
using System;
class HelloClass
{
public static int Main(string[ ] args)
{
Console.WriteLine("Command Line parameters");
for (int x = 0; x < args.Length; x++) // foreach (string s in args)
Console.WriteLine("Args: {0}", args[x]);
return 0;
}
}

57
CONSTRUCTORS
 Works almost same as C++
 "new" is the de facto standard to create an object
instance
 Example ( illegal ) Correct version
HelloClass c1; HelloClass c1 = new HelloClass();
c1.SayHi(); c1.SayHi();
 C# object variables are references to the objects in memory
and not the actual objects
 Garbage collection is taken care by .NET
58
EXAMPLE (Point.cs)
class Point
{
public Point()
{ Console.WriteLine("Default Constructor"); }
public Point(int px, int py)
{ x = px; y = py; }
public int x; Program
public int y; Entry Point
}
class PointApp
{
public static void Main(string[ ] args)
{
Point p1 = new Point(); // default constructor called
Point p2;
p2 = new Point(10, 20); // one –arg constructor called
Console.WriteLine("Out: {0}\t{1}", p1.x, p1.y);
Console.WriteLine("Out: {0}\t{1}", p2.x, p2.y);
}
}
Default Values
 Public variables/members automatically get default values
 Example
class Default
{
public int x; public object obj;
public static void Main (string [ ] args)
{
Default d = new Default();
// Check the default value
}
}
 Local members/variables must be explicitly initialized
public static void Main (string [ ] args)
{
int x;
Console.WriteLine(x); // Error
}
60
BASIC INPUT & OUTPUT
 System.Console Class
 Write(), WriteLine(), Read(), and ReadLine()
 Example (Read and Write a string):
// RW.cs
using System;
class BasicRW
{
public static void Main (string [ ] args)
{
string s;
Console.Write("Enter a string: ");
s = Console.ReadLine();
Console.WriteLine("String: {0}", s);
}
}
61
Basic IO…
// IO.cs
using System;
class BasicIO
{
public static void Main(string[ ] args)
{
int theInt = 20;
float theFloat = 20.2F; // double theFloat = 20.2; is OK
string theStr = “AIT";
Console.WriteLine("Int: {0}", theInt);
Console.WriteLine("Float: {0}", theFloat);
Console.WriteLine("String: {0}", theStr);
// array of objects
object[ ] obj = {“AIT", 20, 20.2};
Console.WriteLine("String: {0}\n Int: {1}\n Float: {2}\n", obj);
}
}
.NET String Formatting
1. C or c Currency ($) Example
2. D or d Decimal // Format.cs
using System;
3. E or e Exponential class Format
4. F or f Fixed point {
5. G or g General public static void Main (string [ ] args)
6. N or n Numerical {
7. X or x Hexadecimal Console.WriteLine("C Format: {0:c}", 9999);
Console.WriteLine("D Format: {0:d}", 9999);
Console.WriteLine("E Format: {0:e}", 9999);
Console.WriteLine("F Format: {0:f}", 9999);
C Format: $9,999.00
Console.WriteLine("G Format: {0:g}", 9999);
D Format: 9999 Console.WriteLine("N Format: {0:n}", 9999);
E Format: 9.999000e+003 Console.WriteLine("X Format: {0:x}", 9999);
F Format: 9999.00 }
}
G Format: 9999
N Format: 9,999.00
X Format: 270f
63
Value and Reference Types
 .NET types may be value type or reference type
 Primitive types are always value types including
structures
 These types are allocated on the stack. Outside the
scope, these variables will be popped out.
 However, classes are not value type but reference
based

64
Example - 1
public void SomeMethod()
{
int i = 30; // i is 30
int j = i; // j is also 30
int j = 99; // still i is 30, changing j will not change i
}

65
Example - 2
struct Foo
{
public int x, y;
}

public void SomeMethod()


{
Foo f1 = new Foo();
// assign values to x and y
Foo f2 = f1;
// Modifying values of f2 members will not change f1 members
….
}
66
Class Types
 Class types are always reference types
 These are allocated on the garbage-collected heap
 Assignment of reference types will reference the same object
 Example:
class Foo
{
public int x, y;
}
 Now the statement Foo f2 = f1; has a reference to the object
f1 and any changes made for f2 will change f1

67
Value Types containing
Reference Types
 When a value type contains other reference type,
assignment results only "reference copy"
 You have two independent structures, each one
pointing to the same object in memory – "shallow
copy"
 For a more deeper copy, we must use ICloneable
interface
 Example: ValRef.cs

68
Example InnerRef valWithRef = new
// ValRef.cs InnerRef("Initial Value");
// This is a Reference type – because it is a class
class TheRefType
valWithRef.structData = 666;
{
public string x;
public TheRefType(string s) valWithRef
{ x = s; }
structData = 666
}
// This a Value type – because it is a structure type refType x=
struct InnerRef "I am NEW"
"Initial Value"
{ valWithRef2
public TheRefType refType; // ref type
public int structData; // value type structData = 777

public InnerRef(string s) refType


{
refType = new TheRefType(s);
structData = 9; InnerRef valWithRef2 = valWithRef;
}
} valWithRef2.refType.x = "I am NEW";
valWithRef2.structData = 777
Master Node : System.Object
 Every C# data type is derived from the base class
called System.Object
class HelloClass
{ .... } is same as

class HelloClass : System.Object


{ ....}

70
Example

namespace System {
public class Object can be overridden
{ by derived class
public Object();
public virtual Boolean Equals(Object obj);
public virtual Int32 GetHashCode();
public Type GetType();
public virtual String ToString();
protected virtual void Finalize();
protected Object MemberwiseClone();
public static bool Equals(object objA, object objB);
public static bool ReferenceEquals(object objA, object objB);
}
}
71
Core Members of System.Object
Equals() Returns true only if the items being compared refer
to the exact same item in memory
GetHashCode() Returns an integer that identifies a specific object
instance
GetType() Returns System.Type
ToString() Returns <namespace.class name> in string format

Finalize() For object removal (garbage collection)


MemberwiseClone() Returns a new object which is member-wise copy
the current object

72
Create System.Object Methods
// ObjTest.cs ToString: ObjTest
using System;
GetHashCode: 1
class ObjTest
{ GetType: System.Object
public static void Main (string [ ] args) Same Instance
{
ObjTest c1 = new ObjTest();

Console.WriteLine("ToString: {0}", c1.ToString());


Console.WriteLine("GetHashCode: {0}", c1.GetHashCode());
Console.WriteLine("GetType: {0}", c1.GetType().BaseType);

// create second object


ObjTest c2 = c1;
object o = c2;
if (o.Equals(c1) && c2.Equals(o))
Console.WriteLine("Same Instance");
}
} 73
Overriding System.Object Methods
 overriding is the process of redefining the behavior of an inherited virtual
member in a derived class
 We can redefine the behavior of virtual methods by overiding
 Example ToString(), Equals(), etc.
class Person
{
public Person(string fname, string lname, string ssn, byte a)
{
firstName = fname;
lastName = lname;
SSN = ssn;
age = a;
}
public Person() { }
public string firstName, lastName, SSN;
public byte age;
} 74
Overriding ToString()
 To format the string returned by System.Object.ToString()
using System.Text;
class Person
{
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("[FName = {0}", this.firstName);
sb.AppendFormat("LName = {0}", this.lastName);
sb.AppendFormat("SSN = {0}", this.SSN);
sb.AppendFormat("Age = {0}]", this.age);
return sb.ToString();
}

} 75
Overriding Equals()
 Equals() returns true if and only if the two objects
being compared reference the same object in
memory
 We can override this behavior and design when two
objects have the same value (value-based). That is,
when name, SSN, age of two objects are equal, then
return true else return false.

76
Example
class Person
{
public override bool Equals(object o)
{
Person temp = (Person) o;
if (temp.firstName == this.firstName &&
temp.lastName == this.lastName &&
temp.SSN == this.SSN &&
temp.age == this.age) return true;
else return false;
}

}
Overriding GetHashCode()
 When a class override Equals(), it should also override
GetHashCode()
 Returns All custom types will be put in a
System.Collections.Hashtable type. The Equals() and
GetHashCode() methods will be called behind the scene to
determine the correct type to return from the container
 Generation of hash code can be customized. In our example
we shall use SSN – a String member that is expected to be
unique
 Example: refer to: Override.cs
public override int GetHashCode()
{ return SSN.GetHashCode(); }
C# Data Types

 every intrinsic C# data type is actually an alias to an


existing type defined in the System namespace.

 Each C# data type aliases a well-defined structure


type in the System namespace.

 C# defines a number of data types,but only a subset


of the whole are complaint with the rules of the CLS.
79
C# Data Types
C# Alias CLS ? System Type Range
sbyte No System.SByte -128 to 127
byte Yes System.Byte 0 to 255
short Yes System.Int16 -32768 to 32767
ushort No System.UInt16 0 to 65535
int Yes System.Int32 -2,147,438,648 to +2,147,438,647
uint No System.UInt32 0 to 4,294,967,295
long Yes System.UInt64 -9,223,372,036,854,775,808 to +9,…..
ulong No System.UInt64 0 to 18,446,744,073,709,551,615
char Yes System.Char U10000 to U1FFFF
float Yes System.Single 1.5×10-45 to 3.4×1038
double Yes System.Double 5.0×10-324 to 1.7×10308
bool Yes System.Boolean true or false
decimal Yes System.Decimal 100 to 1028
string Yes System.String Limited by system memory
object Yes System.Object Anything at all
Hierarchy of System Types
Object Boolean
UInt16
Byte
Type UInt32
Char
String ValueType UInt64
(derived one Decimal
is Void
Array
struct type Double
and not DateTime
Exception Int16
class)
Guid
Delegate Int32
TimeSpan
Int64
Single
MulticastDelegate SByte
81
Enumerations and Structures
Examples
 Integers
 UInt16.MaxValue
 UInt16.MinValue
 Double
 double.Maxvalue
 double.MinValue
 double.PositiveInfinity
 double.NegativeInfinity
 Boolean
 bool.FalseString
 bool.TrueString

82
Examples
 Char
 char.IsDigit('K')
 char.IsLetter('a') or char.IsLetter("100", 1)
 char.IsWhiteSpace("Hi AIT", 2)
 char.IsPunctuation(',')

83
Value Type and Reference Type
 Value Type
 Value types are used directly by their values
 int, float, char, enum, etc. are value types
 These types are stored in a Stack based memory
 Example: int Age = 42; or int Age = new int(42);

Stack

int 42

84
Reference Type
 These types are allocated in a managed Heap
 Objects of these types are indirectly referenced
 Garbage collection is handled by .NET
Objects
Reference Variables

Shape rect = new Shape();


Shape

Shape Temprect = rect; Shape

Shape Newrect = new Shape();


85
Boxing and UnBoxing
 Boxing
 Explicitly converting a value type into a corresponding
reference type
 Example:
int Age = 42;
object objAge = Age;
 No need for any wrapper class like Java
 C# automatically boxes variables whenever needed. For
example, when a value type is passed to a method
requiring an object, then boxing is done automatically.

86
UnBoxing
 Converting the value in an object reference (held in heap) into
the corresponding value type (stack)

 Remember that we can only unbox a variable that has


previously been boxed.
 Example:
object objAge;
int Age = (int) objAge; // OK
string str = (string) objAge; // Wrong!
Int m=500;object om=m; byte n=(byte)om; //error
 The type contained in the box is int and not string!
87
Boxing and UnBoxing Example
using System;
class Program
{ static void Main(string[] args)
{
// Create an int (value type).
int myInt = 99;
// Because myInt is passed into a method prototyped to take an object, myInt is 'boxed' automatically.

UseThisObject(myInt);
Console.ReadLine();

static void UseThisObject(object ob1)


{

Console.WriteLine("Value of o is: {0}", ob1);


Console.WriteLine(ob1.GetType());
Console.WriteLine(((int)ob1).GetType());

}
88
}
Defining Program Constants
 ‘const’ is the keyword used to define fixed unalterable
value for a variable.
 C# ‘const’ keyword cannot be used to qualify
parameters or return values.
 A constant data is computed at compile time .
Therefore it cannot be assigned to an object
reference.
Ex : const x=25;
Object o=x; //wrong assignment
89
Defining Program Constants
 When accessed by another type these constants must be referred via fully
qualified name.
using System;
class Mycon
{ public const int x=5;
public const string str=“I am Constant”;
public static void Main()
{
Const string str1=“I am rock “; //local constant within method scope
Console.WriteLine(“{0}\n{1}\n{2}”,x,str,str1);
}
}

90
Referencing Constant Data Across
Types

 But if the constants x and str were referred in some other


type, then we have to use absolute pathname.
class CallConst {
public static void Main()
{ const string str1=“I am rock”;
Console.WriteLine(“{0}\n{1}\n{2}\n”,
Mycon.x,Mycon.str,str1);
}
}
91
C# Iteration Constructs
 for loop
 foreach-in loop
 while loop
 do-while loop

92
The for Loop
 For loop is used to iterate over a block of code a fixed number of times.C#
for Loop is same as C, C++, Java, etc
 Example:
static void Main(string[] args)
{
// Note! 'i' is only visible within the scope of the for loop.
for(int i = 0; i < 10; i++)
{
Console.WriteLine("Number is: {0} ", i);
}
// 'i' is not visible here.
}
 You can use "goto", "break", "continue", etc like other languages

93
The foreach/in Loop
 The C# foreach keyword allows you to iterate over all items within an array, without the need to test for
the array’s upper limit.

using System;
class ForEach
{
public static void Main(string[] args)
{
string[ ] Names = new string [ ] {“Satish 99", “Thimmaih 90",
“kiran 35", “Sudhir 67"};
int n = 0;
foreach (string s in Names)
{
if (s.IndexOf(“9") != -1)
n++;
}
Console.WriteLine("No. of Students scored above 90 = {0}", n);
}
}

94
The while and do/while Loop
class FileRead
{
public static void Main(string[] args)
{
try
{
StreamReader strReader = File.OpenText(“c:\\Emp.dat");
string strLine = null;
while (strReader.ReadLine( ) != null)
{
Console.WriteLine(strLine);
}
strReader.Close();
}
catch (FileNotFoundException e)
{
Console.WriteLine(e.Message);
}
}
}

 While statement is useful for those times when you are uncertain how long it might take for a terminating condition to be
met
95
Control Statements
 if, if-else Statements
 Unlike in C and C++, the if/else statement in C# operates only on Boolean expressions,
not ad hoc values such as –1, 0.
 Relational operators like ==, !=, <, >, <=, >=, etc are all allowed in C#
 Conditional operators like &&, ||, ! are also allowed in C#
 Beware of the difference between int and bool in C#
 Example
// This is illegal, given that Length returns an int, not a bool.

string thoughtOfTheDay = "You CAN teach an old dog new tricks";


if(thoughtOfTheDay.Length) //error
{
...
}

96
The switch Statement
 Same as C, C++, etc. with some restrictions
 Every case should have a break statement to avoid
fall through (this includes default case also)
 Example switch(country)
switch(country) { // Correct
{ case "India": HiIndia();
// Error – no break break;
case "India": case "USA": HiUSA();
case "USA": break;
default: default: break;
} }
97
Switch Example
static void Main(string[] args)
{
Console.WriteLine("1 [C#], 2 [VB.NET]");
Console.Write("Please pick your language preference: ");
string langChoice = Console.ReadLine();
int n = int.Parse(langChoice);
switch (n)
{
case 1: Console.WriteLine("Good choice, C# is a fine language.");
break;
case 2: Console.WriteLine("VB .NET: OOP, multithreading, and more!");
break;
default: Console.WriteLine("Well...good luck with that!");
break;
}
}

98
goto Statement
 goto label;
 Explicit fall-through in a switch statement can be
achieved by using goto statement
 Example: switch(country)
{
case "India": HiIndia();
goto case "USA";
case "USA": HiUSA();
break;
default: break;
}

99
C# Operators
 All operators that you have used in C and C++ can
also be used in C#
 Example: +, -, *, /, %, ?:, ->, etc
 Special operators in C# are : typeof, is and as
 The is operator is used to verify at runtime whether
an object is compatible with a given type
 The as operator is used to downcast between types
 The typeof operator is used to represent runtime type
information of a class
100
Example - is
 Common use of this operator is to determine if a given object
supports a particular interface.
public void DisplayObject(object obj)
{
if (obj is int)
Console.WriteLine("The object is of type integer");
else
Console.WriteLine("It is not int");
}
101
Example - as
 Using as, you can convert types without raising an exception
 In casting, if the cast fails an InvalidCastException is raised
 But in as no exception is raised, instead the reference will be
set to null
static void ChaseACar(Animal anAnimal)
{
Dog d = anAnimal as Dog; // Dog d = (Dog) anAnimal;
if (d != null)
d.ChaseCars();
else
Console.WriteLine("Not a Dog");
}

102
Defining Custom Class methods

 Every method must be present inside a class or


struct(global methods are not allowed in c#).
 Custom methods may or may not return values, may
or may not take parameters.
 Custom methods may be declared non-static and
static.
 A method must specify the level of accessibility.

104
Method Access Specifiers
 public void MyMethod() { } » Accessible anywhere
 private void MyMethod() { } » Accessible only from
the class where defined
 protected void MyMethod() { } » Accessible from its own
class and its descendent
 internal void MyMethod() { } » Accessible within the
same Assembly
 void MyMethod() { } » private by default
 protected internal void MyMethod() { }
» Access is limited to the current assembly or types derived from
the defining class in the current assembly.

105
Static Methods
 What does 'static' method mean?
 Methods marked as 'static' may be called directly from class
level
 This means, there is no need to create an instance of the
class (i.e. an object variable) and then call. This is similar to
Console.WriteLine()
 If it was not a static method then its access would be
Console C=new Console(); C.WriteLine();
 public static void Main() – why static?
 At run time Main() can be invoked without any object variable
of the enclosing class
107
Example
public class MyClass
{
public static void MyMethod()
{…}
}
public class StaticMethod
{ If MyMethod() is not declared
as static, then
public static void Main(string[ ] args)
{ MyClass obj = new MyClass();
obj.MyMethod();
MyClass.MyMethod();
}
}

108
Static Data
 In addition to static methods, a type may also define static data.
 when a class defines non static data, each object of this type maintains a
private copy of the field.
 Example :
// This class has a single piece of nonstatic data.
class SavingsAccount
{
public double currBalance;
public SavingsAccount(double balance)
{ currBalance = balance;}
}
 When you create SavingsAccount objects, memory for the currBalance
field is allocated for each instance.

109
Static Data

 Static data, on the other hand, is allocated once and shared among all
object instances of the same type.

class SavingsAccount
{
public double currBalance;
public static double currInterestRate = 0.04;
public SavingsAccount(double balance)
{
currBalance = balance;
}
}

110
Static Data

 If you were to create three instances of SavingsAccount


static void Main(string[] args)
{
// Each SavingsAccount object maintains a copy of the currBalance field.

SavingsAccount s1 = new SavingsAccount(50);


SavingsAccount s2 = new SavingsAccount(100);
SavingsAccount s3 = new SavingsAccount(10000.75);
}
111
Static Data

 The in-memory data allocation would look something


like

112
Stack Class (StaticMethod folder)
using System;
public class Stack
{
public static void Push(string s)
{
items[++top] = s;
}
public static string Pop()
{
return (items[top--]);
}
public static void Show()
{
for (int i = top; i >= 0; i--)
Console.WriteLine(items[i]);
}
private static string[ ] items = new string[5];
private static int top = -1;
}
Stack Class….
class StaticMethod
{
public static void Main(string[] args)
{
Console.WriteLine("Stack Contents:");
Stack.Push(“AIT");
Stack.Push(“BMSCE");
Stack.Show();
Console.WriteLine("Item Popped=> " + Stack.Pop());
Console.WriteLine("Stack Contents:");
Stack.Show();
}
}
Parameter Passing Methods
 Default » Value parameter
 out » Output parameter (called member)
 ref » Same as pass-by-reference
 params » Variable number of parameters
within a single parameter

115
“Out” Parameter passing Example

using System;

class OutParam
{

public static void add(int x,int y,out int ans)


{
ans =x+y;
}

public static void Main()


{
int x=5,y=4,result=0;
add(x,y,out result);
Console.WriteLine("{0}+{1}={2}",x,y,result);
}
}
116
Parameter Passing
 One advantage of out parameter type is that we can return
more than one value from the called program to the caller

Calling Called
Program Program

a, b x, y

r out ans

s.Add(a, b, out r); public void Add(int x, int y, out int ans)

117
The ref method
using System;
class Ref
{
public static void Swap(ref int x, ref int y)
{
int temp;
temp = x;
x = y;
y = temp;
}

static void Main(string[ ] args)


{
int a = 10; int b = 20;
Console.WriteLine("Before Swap => {0} \t {1}", a, b);
Ref.Swap(ref a, ref b);
Console.WriteLine("After Swap => {0} \t {1}", a, b);
}
} 118
The params method
 To achieve variable number of parameters in a
Method declaration
 The params parameter must be a single dimensional
array (else you get an error)
 You can define any object in the parameter list

119
Example
using System;
class Params
{
public static void DispArrInts(string msg, params int[ ] list)
{
Console.WriteLine(msg);
for (int i = 0; i < list.Length; i++)
Console.WriteLine(list[i]);
}
static void Main(string[ ] args)
{
int[ ] intArray = new int[ ] {1, 2, 3};
DispArrInts("List1", intArray);
DispArrInts("List2", 4, 5, 6, 7); // you can send more elements
DispArrInts("List3", 8,9); // you can send less elements
}
}
120
Generic use of params
 Instead of using only an integer list for the params parameter, we
can use an object
public class Person
{
private string name;
private byte age;
public Person(string n, byte a)
{
name = n;
age = a;
}
public void PrintPerson()
{ Console.WriteLine("{0} is {1} years old", name, age); }
}
121
pass any object
public static void DisplayObjects(params object[ ] list)
{
for (int i = 0; i < list.Length; i++)
{
if (list[i] is Person)
((Person)list[i]).PrintPerson();
Output:
else 777
Console.WriteLine(list[i]); John is 45 years old
Instance of System.String
}
Console.WriteLine();
}
Calling Program:
Person p = new Person("John", 45);
DisplayObjects(777, p, "Instance of System.String"); 122
Passing Reference Types –
By Value
 If a reference type is passed by value, the calling program may
change the value of the object's state data, but may not change
the object it is referencing
public static void PersonByValue(Person p)
{
// will change state of p
p.age = 60;
// will not change the state of p
p = new Person("Nikki", 90);
}
123
Passing Reference Types –
By Reference
 If a class type is passed by reference, the calling program
may change the object's state data as well as the object it is
referencing
public static void PersonByRef(ref Person p)
{
// will change state of p
p.age = 60;
// p will point to a new object
p = new Person("Nikki", 90);
}
124
Calling Program
// Pass by Value
Console.WriteLine("Passing By Value...........");
Person g = new Person("Geetha", 25);
g.PrintPerson();
Passing By Value...........
Geetha is 25 years old
PersonByValue(g);
Geetha is 60 years old
g.PrintPerson();

// Pass by Reference
Console.WriteLine("Passing By Reference........");
Person r = new Person("Geetha", 25);
r.PrintPerson(); Passing By Reference........
Geetha is 25 years old
PersonByRef(ref r); Nikki is 90 years old
r.PrintPerson();
125
Arrays in C#
 C# arrays are derived from System.Array base class.Memory
for arrays is allocated in heap
 Arrays in C# are declared as
type [ ] arrayname;
 Example
 Int [ ] x ; // declare integer array reference
 int [ ] intArray = new int [10]; // integer array
 string [ ] strArray = new string[10]; // string array
 int[2] Age = {34, 70}; // Error, requires new keyword
 Person[ ] Staff = new Person[2]; // object array
 strAarray[0] = “AIT"; // assign some value
 int [ ] Age = new int[3] {25, 45, 30}; // array initialization

126
Multidimensional Arrays
 Rectangular Array
 int[ , ] myMatrix; // declare a rectangular array
 int[ , ] myMatrix = new int[2, 2] { { 1, 2 }, { 3, 4 } }; // initialize
 myMatrix[1,2] = 45; // access a cell
 Jagged Array
 int[ ][ ] myJaggedArr = new int[2][ ]; // 2 rows and variable columns
 for (int i=0; i < myJaggedArr.Length; i++)
myJaggedArr[i] = new int[i + 7];
 Note that, 1st row will have 7 columns and 2nd row will have 8
columns
127
System.Array Base Class

BinarySearch( ) Finds a given item


Clear( ) Sets range of elements to 0/null
CopyTo( ) Copy source to Destination array
GetLength( ) To determine no. of elements
Length Length is a read-only property
GetLowerBound( ) To determine lower and upper bound
GetUpperBound( )
GetValue( ) Retrieves or sets the value of an array cell, given its
SetValue( ) index
Reverse( ) Reverses the contents of one-dimensional array
Sort( ) Sorts a one-dimensional array
Array Example
static void Main(string[] args)
{
string[] firstNames = { "Steve", "Dominic", "Swallow", "Baldy"} ;
Console.WriteLine("Here is the array:"); // Print names as declared.
for(int i = 0; i < firstNames.Length; i++)
Console.Write("Name: {0}\t", firstNames[i]);
Console.WriteLine("\n");

Array.Reverse(firstNames);
Console.WriteLine("Here is the array once reversed:"); // Reverse array and print.
for(int i = 0; i < firstNames.Length; i++)
Console.Write("Name: {0}\t", firstNames[i]);
Console.WriteLine("\n");

Console.WriteLine("Cleared out all but Baldy...");


Array.Clear(firstNames, 1, 3); // Clear out all but Baldy.
for(int i = 0; i < firstNames.Length; i++)
Console.Write("Name: {0}\t", firstNames[i]);
Console.ReadLine();
}
129
Example
public static int[ ] ReadArray( ) // reads the elements of the array
{
int[ ] arr = new int[5];
for (int i = 0; i < arr.Length; i++)
arr[i] = arr.Length - i;
return arr;
}
public static int[ ] SortArray(int[ ] a)
{
System.Array.Sort(a); // sorts an array
return a;
}
130
Calling Program
public static void Main(string[ ] args)
{
int[ ] intArray;

intArray = ReadArray( ); // read the array elements


Console.WriteLine("Array before sorting");
for (int i = 0; i < intArray.Length; i++)
Console.WriteLine(intArray[i]);

intArray = SortArray(intArray); // sort the elements


Console.WriteLine("Array after sorting");
for (int i = 0; i < intArray.Length; i++)
Console.WriteLine(intArray[i]);
}

131
String Manipulations in C#

 A string is a sequential collection of Unicode characters, typically used to represent


text. The C# string keyword is a shorthand notation of the System.String type.

 If it is necessary to modify the actual contents of a string, use the


System.Text.StringBuilder class.

 C# supports two types of strings


 Immutable
 Meaning that we cannot modify the characters contained
in them
 Mutable
 Meaning that we can modify the characters contained
in them

 C# also supports a feature known as regular expressions that can be used for
complex string manipulations and pattern matching.
132
System.Array Base Class

Length This property returns the length of the current string

Concat ( ) This method returns a new string that is composed of two


discrete strings
compareTo ( ) Compares two strings
Copy( ) This method returns a fresh new copy of an existing string
Insert ( ) Used to insert a string within a given string.
PadLeft() Used to pad a string with some character
PadRight()
Remove ( ) These methods remove or replace characters.
Replace ( )
ToUpper() These methods create a copy of a given string in
ToLower() uppercase or lowercase.
133
More on String Methods
 CompareTo() – int x = s1.CompareTo(s2); and returns
an int
 Remove() – Deletes a specified number of characters
from this instance beginning at a specified position.
 public string Remove (int startIndex, int count );
 Insert() - Inserts a specified instance of String at a
specified index position in this instance.
 public string Insert (int startIndex, string value );
 ToLower() - Returns a copy of this String in lowercase
 Example: s = s.ToUpper();
136
System.Text.StringBuilder
 Like Java, C# strings are immutable. This means, strings can not
be modified once established
 For example, when you send ToUpper() message to a string object,
you are not modifying the underlying buffer of the existing string
object. Instead, you return a fresh copy of the buffer in uppercase
 It is not efficient, sometimes, to work on copies of strings –
solution?
Use StringBuilder from System.Text!

Note: A String is called immutable because its value cannot be modified once it has
been created. Methods that appear to modify a String actually return a new
String containing the modification. If it is necessary to modify the actual
contents of a string-like object, use the System.Text.StringBuilder class.

137
Example
using System;
using System.Text;
class MainClass
{
public static void Main()
{
StringBuilder myBuffer = new StringBuilder("Buffer");
// create the buffer or string builder
myBuffer.Append( " is created");
Console.WriteLine(myBuffer);
// ToString() converts a StringBuilder to a string
string uppercase = myBuffer.ToString().ToUpper();
Console.WriteLine(uppercase);
string lowercase = myBuffer.ToString().ToLower();
Console.WriteLine(lowercase);
}
}
Enumerations in C#
 An Enumeration is a user-defined integer type which
provides a way for attaching names to numbers.
 The enum keyword automatically enumerates a list
of words by assigning them values 0,1,2.
 This facility provides an alternative means of
creating ‘constant’ variable names.
 Example
 enum Color {Red ,Blue,Green,Yellow}
 enum Position {Off,On}

139
Enumerator initialization
 Mapping symbolic names to  The internal type used for
numerals
 Example - 1
enumeration is System.Int32
enum Colors
 Using Enumerations
{
Red, // 0
Colors c;
Green, // 1 c = Colors.Blue;
Blue // 2
} Console.WriteLine(c); // Blue
 Example - 2
enum EmpType : byte
{
Manager = 10,
Worker = 1,
Contractor = 100,
VP
}
140
System.Enum Base Class
Converts a value of an enumerated type to its
Format()
string equivalent
Retrieves the name for the constant in the
GetName()
enumeration
Returns the type of enumeration
GetUnderlyingType() Console.WriteLine(Enum.GetUnderlyingType(typeof
(Colors))); // System.Int32
Gives an array of values of the constants in
GetValues()
enumeration
To check whether a constant exists in enum
IsDefined()
if (Enum.IsDefined(typeof(Colors), "Blue") ….
Converts string/value to enum object
Parse() Colors CarColor = (Colors)Enum.Parse(typeof(Colors),
141
"Red");
 Console.WriteLine(Enum.GetUnderlyingType(typeof(Staff)));
 Returns : System.Int32

 if(Enum.IsDefined(typeof(Colors), “Yellow"))
Console.WriteLine("Yes, we have Yellow Color ");
else
Console.WriteLine("No, we don’t have Yellow Color ...");

142
Example
Array obj = Enum.GetValues(typeof(Colors));
foreach(Colors x in obj)
{
Console.WriteLine(x.ToString());
Console.WriteLine("int = {0}", Enum.Format(typeof(Colors), x, "D"));
}
Output
Red
int = 0
Blue
int = 1
Green
int = 2
143
Structures in C#
 Structures are a way to achieve the benefits of
object orientation(i.e.,encapsulation) while having
the efficiency of stack-allocated data.
 Structures can contain constructors (must have
arguments). We can't redefine default constructors
 It can implement interfaces
 Can have methods – in fact, many!
 There is no System.Structure class! (derived from
System.ValueType).
144
Example
using System;
struct STUDENT
{
public int RegNo;
public string Name;
public int Marks;
public STUDENT(int r, string n, int m)
{
RegNo = r;
Name = n;
Marks = m;
}
}
class MainClass
{
public static void Main()
{
STUDENT s;
s.RegNo = 111;
s.Name = “SATISH";
s..Marks = 99;

STUDENT SomeOne = new STUDENT(222,"Ravi",90);


}
}
Designing Custom Namespaces
 System is the .NET's existing
namespace
 Using the keyword namespace, we CompanyName
can define our own namespace
 Putting all classes in a single Server UserInterface
namespaces may not be a good
practice
 Typical namespace organization for a Session IO Desktop WebUI

large project
 To use a namespace:
 (1) System.Xml.XmlTextReader tr;
 (2) using System.Xml;
XmlTextReader tr;

146
Example
 Assume that you are developing a collection of graphic
classes: Square, Circle, and Hexagon
 To organize these classes and share, two approaches could
be used:
// shapeslib.cs
using System;
Namespace MyShapes;
{
public class Square { …}
public class Circle { …} NOTE : MyShape namespace
public class Hexagon { …} Acts as the conceptual
} “container “ of each type

147
Alternate Approach
// Square.cs
using System;  All the three classes Square, Circle, and
namespace MyShapes Hexagon are put in the namespace
{ MyShapes
class Square { … }
} using System;
// Circle.cs using MyShapes;
using System; namespace MyApplication
namespace MyShapes {
{ class ShapeDemo
class Circle { … } {
} …..
// Heagon.cs Square sq = new Square();
using System; Circle Ci = new Circle();
namespace MyShapes Heagone he = new Heagon();
{ …….
class Hexagon { … } }
} }
defined in MyShapes namespace
Resolving Name clashes in
namespaces
Using System;  The class Square is define in both
Namespace My3DShapes; the namespaces (MyShapes and
{
My3DShpaes)
public class Square { …}
public class Circle { …}  To resolve this name clash, use
public class Hexagon { …} My3DShapes. Square Sq =
} new My3DShapes.Square();
using System;  Qualify the name of the class with the
using MyShapes; appropriate namespace
usingMy3DShapes;  The default namespace given in VS
……..
IDE is the name of the project
// Error!
Square Sq = new Square();
…….

149
End of
Chapter 3
151
Chapter - 4

OOP with C#

152
Objectives
 Basic Class in C#
 Visibility
 Encapsulation
 Accessor (get) and Mutator (set)
 Named Property
 Inheritance
 Sealed classes
 Polymorphism
 Abstract Class and Method
153
C# Classes
 A Class is a custom User Defined Type (UDT)
 A Class consists of data (attributes) and functions
(methods)
 Example: To model a generic Employee, we can
define an Employee Class

154
Employee Class
Employee

attributes:
string fullname;
int empID;
float currPay;

methods:
void GiveBonus(float amount);
void DisplayStats();

155
Source Code
using System;
namespace Employee
{
public class Employee
{
// private data
private string fullName;
private int empID;
private float currPay;
// Default ctor.
public Employee(){ }
// Custom ctor
public Employee(string fullName, int empID, float currPay)
{
// Assign internal state data. Note use of 'this' keyword
this.fullName = fullName;
this.empID = empID;
this.currPay = currPay;
}
156
Source Code (Contd…)
// Bump the pay for this emp.
public void GiveBonus(float amount)
{currPay += amount;}

// Show the state


public void DisplayStats()
{
Console.WriteLine("Name: {0}", fullName);
Console.WriteLine("Pay: {0}", currPay);
Console.WriteLine("ID: {0}", empID);
}
public static void Main(string[ ] args)
{
Employee e = new Employee("Joe",111,23987.50F);
e.GiveBonus(200);
e.DisplayStats();

}
}
}
157
Method Overloading and 'this'
 Overloading of Methods is same as C++. Constructors can be overloaded.
 For method resolution, return type alone is not necessary!
 Is the keyword 'this' always necessary?
 Yes, if the parameter name and the class member name are same.
Otherwise No!
 Static member functions can't use 'this' keyword. Why?
 The keyword 'this' can also be used to force one constructor to call another
during the object creation
 Ex: public Employee(string fullName) : this(fullName, GetEmpId(), currPay)
{}

158
Basic OOP Concepts
 Encapsulation
 Hiding unnecessary implementation details
 Inheritance
 "is-a" and "has-a" relationship
 "is-a" means sub-classes or derived classes
 "has-a" means containment or delegation
 Polymorphism
 It is the ability of the language to treat related objects the same way
 When sub-classes override the behavior defined by base a class,
they are essentially redefining how they respond to the same
message

159
Examples
 Encapsulation
DBReader f = new DBReader(); // details are hidden
f.Open("@C:\foo.mdf"); is-a Relationship

// process the database file Object


f.Close();
 Inheritance Shape
 Polymorphism
Hexagon
Shape
void Draw( )
has-a Relationship
Hexagon Circle
Draw() Draw() Car

Radio 160
More Details: (1) Encapsulation
 The main objective of encapsulation is: the object's instance
should be allowed to access the internal member data
directly. It also provides the integrity of state data. How to do
this?
 Using private, public, protected, and protected internal
keywords
 To manipulate the private data, C# provides two methods:
 Define traditional accessor and mutator methods
 Define a named property

161
Example
 Accessor
class Employee
{
private string fullName;
public string GetName() { return fullName; }
…………..
}
 Mutator
class Employee
{
private string fullName;
public string SetName(string n)
{ fullName = n; }
…………….
}

162
Class Properties
 You can define a named property to avoid using two
different get and set methods
 The property is a single named field which wraps the private
data. These property names can then be used in Main( ).
 Ex: Assume EmpID is the name of the property
public static void Main()
{
Employee e = new Employee();
p.EmpID = 111; // set
Console.WriteLine(e.EmpID); // get
}

163
C# get and set Methods
using System; class Class1
namespace get_set {
{ static void Main(string[] args)
class MyClass {
{
MyClass obj = new MyClass();
private int a;
obj.A = 20;
public int A // property
{ Console.WriteLine(obj.A);
get // accessor }
{ }
return a; }
}
set // mutator  get block – accessor
{
a = value;  set block – mutator
}  A – named property
}
164
}
Read-Only and Write-Only Properties
 The named property A in the previous slide was able to read
and write. How to restrict the access of A as R/W?
 For Read-Only: simply define a property without a set block
 For write-only: simply define a property without a get block
 Ex: public float Pay public float Pay
{ {
get { return currPay; } set { currPay
= value; }
} }

165
static: properties and constructors
 The static keyword can be used for properties also
 The only difference is that, now these properties are bound
to a class and not to an instance
Ex: Employee.EmpID = 111;
 Can a constructor be declared as static?
 Yes, but it is strange! Why? Because, constructors are
executed during object creation
 Static constructors are used to initialize static data

166
Example – static property
public class Employee
{
private static string companyName;
public static string Company
{
get { return companyName; }
set {companyName = value; }
}
}
public static void Main(string[ ] args)
{
Employee.Company = "Microsoft";
Console.WriteLine("The name is {0}", Employee. Company);
}

167
Example – static constructor
public class Employee
{
private static string companyName;
static Employee()
{ companyName = "Microsoft"; }
}
public static void Main(string[ ] args)
{
// below statement is not needed
// Employee.Company = "Microsoft";
Console.WriteLine("The name is {0}",
Employee.Company);
}

168
Read-Only Fields
 Read-Only properties provide data preservation: keyword to be used is:
"readonly"
 Ex: public readonly int rofield;
 You can't assign any value to the readonly fields, except in a constructor
 Ex: void SomeMethod() { rofield =
123; } // Error
 Static readonly fields can also be used. It is useful to associate many
constant values bound to a class.
 It may be look similar to 'const' declaration. The difference, however, is that
const is resolved at compile-time and static readonly is resolved at run-
time.
 The other context in which it is valid to pass a readonly field as an out or ref
parameter.

169
More Details: (2) Inheritance
 Inheritance facilitates code reuse
 Inheritance provides dependency between types
 Inheritance comes in two flavors:
 "is-a" relationship
 "has-a" relationship
 Let us start with "is-a" relationship……
SalesPerson
Employee
Manager
170
Manager – Derived Class
using System;
namespace Employee
{
public class Manager : Employee
{
private ulong numberOfOptions;
public ulong NumberOpts
{
get { return numberOfOptions; }
set { numberOfOptions = value; }
}
}
}

171
SalesPerson – Derived Class
using System;
namespace Employee
{
public class SalesPerson : Employee
{
private int numerOfSales;
public int NumbSales
{
get { return numerOfSales; }
set { numerOfSales = value; }
}
}
}

172
Base class and Subclass Constructors
 A subclass constructor automatically calls the base
class constructor, by default
 Example:
public Manager(string fullName, int empID, float currPay, ulong
numberOfOpts)
: base (fullName, empID, currPay)
{ numberOfOptions = numberOfOpts; }
 Refer to: Inheritance project folder for the complete
source code

173
More features of "is-a"
 Multiple Inheritance
 In C#, a given class can have exactly one direct base class
 It is not permitted to have a single type with one or more base
classes
 "protected " Keyword
 You know that a private member can't be accessed by even
subclasses
 "protected " data or methods can be accessed by subclasses
 Sealed Classes
 If you want to design a class that can't be inherited, then use the
keyword: "sealed "
 A sealed class cannot also be an abstract class. It also enables
certain run-time optimizations
174
Example – Sealed Classes
SalesPerson PTSalesPerson
Employee
Manager

 Add a subclass PTSalesPerson for SalesPerson class to


have part – time sales people.
 Since we can't think of more child classes under
PTSalesPerson, we shall seal it
 Sealed classes are most useful for designing standalone
classes. Ex: String class in the System namespace
 Example
public sealed PTSalesPerson : SalesPerson
{ ………. }
175
Containment/Delegation
or has-a relationship

 Let us consider two classes: A Car class and a Radio class


 It is odd to think of Radio is a Car! Instead, we can say a Car has a Radio
 Car – is called as Containing Class
Radio – is called as Contained Class
 To expose the functionality of the inner class to the outside world
requires delegation
 Delegation means adding members to the containing class that make
use of the contained class's functionality (Ex:
theMusicBox.TurnOn(state); )
 Refer to: Containment folder for the complete source code

176
More Details: (3) Polymorphism

 Polymorphism is the ability for classes to provide different implementations


of methods that are called by the same name.
 Polymorphism allows a method of a class to be called without regard to
what specific implementation it provides.
 For Example, assume that you have added a new method to Employee
class as:
public void GiveBonus(float amount)
{ currPay += amount; }
 This method is common for all objects derived from Employee. However,
our objective is to design this to behave differently for Manager and
SalesPerson.
 This means that the subclasses should be able to provide different
interfaces to Employee class
 Polymorphism is achieved through " virtual " and " override " keywords

177
Types of Polymorphism
 Interface polymorphism - Multiple classes may implement the same
interface, and a single class may implement one or more interfaces.
Interfaces are essentially definitions of how a class needs to respond. An
interface describes the methods, properties, and events that a class needs
to implement.
 Inheritance polymorphism - Multiple classes may inherit from a single base
class. By inheriting, a class receives all of the methods, properties, and
events of the base class in the same implementation as the base class.
 Polymorphism through abstract classes - Abstract classes provide
elements of both inheritance and interfaces. An abstract class is a class
that cannot be instantiated itself; it must be inherited.

178
Example

Base Claass
public class Employee
{
public virtual void GiveBonus(float amount)
{ currPay += amount; }
………
}
public class SalesPerson : Employee
{
public override void GiveBonus(float amount)
{
int salesBonus = 0;
if (numberOfSales > 200)
salesBonus = 1000;
base.GiveBonus(amount + salesBonus);
}
}
 You can reuse the base class method by using the keyword base
 Alternatively, the subclass can completely redefine without calling the base class method
179
Abstract Classes
 An abstract class cannot be instantiated directly, and it is a
compile-time error to use the new operator on an abstract
class
 An abstract class is permitted (but not required) to contain
abstract members
 An abstract class cannot be sealed – Why?
 Ex: If the Employee class is declared as abstract, the the
following stmt. gives an error:
Employee e = new Employee();
 What is the need for an abstract class?
 Does it look OK if some one says
"I am an Employee"? or "I am a Sales Person"
180
Example
abstract class A A
{
public abstract void F();
}
abstract class B: A
{
B
public void G() {}
}
class C: B
{
public override void F()
C
{ // actual implementation of F }
}

 The abstract class A introduces an abstract method F.


 Class B introduces an additional method G, but since it doesn't provide an
implementation of F, B must also be declared abstract.
 Class C overrides F and provides an actual implementation. Since there are no
abstract members in C, C is permitted (but not required) to be non-abstract.
181
Shape Class – Design overview
Same as
public abstract class Shape pure
It is more { virtual
intelligent to public virtual void Draw() function of
declare {…} C++
Draw() as }
abstract

public class Circle : Shape public class Hexagon : Shape


{
{…}
public override void Draw()
{ ... }
 The subclass Circle does not override} Draw(), whereas Hexagon does
 Refer to Shapes Project

182
Method Hiding

 Method hiding is opposite of Method overriding


 Assume that Oval is-a type of Circle. Of course you can define a method Draw() which
overrides Draw() of its parent class and provide its own versioning.
 However, if we want to prevent the Oval class from inheriting any previous logic, use
"new" keyword
public class Oval : Circle
{
public Oval(){base.PetName = "Joe";}
// Hide base class impl if they create an Oval.
new public void Draw()
{
Console.WriteLine("Oval with class versioning");
}
}
 new keyword breaks the relationship between base class of abstract Draw() and
the derived class version

183
new Modifier
// The new modifier
using System;
public class MyBaseC
Output:
{ 100
public static int x = 55; 55
public static int y = 22; 22
}

public class MyDerivedC : MyBaseC


{
new public static int x = 100; // Name hiding
public static void Main( )
{
Console.WriteLine(x); // Display the overlapping value of x:
Console.WriteLine(MyBaseC.x); // Access the hidden value of x:
Console.WriteLine(y); // Display the unhidden member y:
}
}

184
End of
Chapter 4

185
Chapter - 5

Exceptions
and
Object Lifetime

186
Chapter Objectives

 What is an Exception? – basics


 System.Exception Class
 Catching an Exception
 System Level Exceptions
 Building Customized Exceptions
 Multiple Exceptions
 Garbage Collection - basics
 What is "finally"?
 Building Finallizable and Disposable Types
187
Ode to Errors, Bugs and Exceptions

 Writing software is a complex task.


 While writing a program several problems are
encountered. no programmer is perfect.
 The problem may be caused by bad code (overflow
bound of an array) or a problem is caused by bogus
user input that has not been accounted for in the
application’s code base(Entering string to account
number).

188
Definitions for three commonly used anomaly-centric terms:

 Bugs: it is an error on the part of the programmer.


 For example
 assume you are programming with unmanaged C++.
 If you make calls on a NULL pointer
 fail to delete allocated memory (resulting in a memory leak), you
have a bug.

 Errors : errors are caused by the individual running your


application
 For example,
 an end user who enters a malformed string into a text box that
requires an SSN.

189
Definitions for three commonly used anomaly-centric terms:

 Exceptions: an Exception is a condition that is


caused by a run-time error in the program.
 For Example :
 attempting to connect to a database that no longer exists,
 opening a corrupted file,
 Contacting a machine that is currently offline
 In each of these cases, the programmer has little
control over these “exceptional” circumstances.

190
Introduction
 An exception is any error condition or unexpected behavior
encountered by an executing program. These are run time
anomalies.
 In the .NET Framework, an exception is an object that inherits
from the System.Exception class
 An exception is thrown from an area of code where a problem
has occurred
 .NET base class libraries define: OutOfMemoryException,
IndexOutOfRangeException, FileNotFoundException, and so
on

191
The Role of .NET Exception Handling

 There are two ways to handle an exception


 Traditional
 Many programmers rolled their own error handling logic
within the context of a given application
 For example, a development team may define a set of
numerical constants that represent known error
conditions, and make use of them as method return
values.

192
The Role of .NET Exception Handling

/* A very C-style error trapping mechanism. */


#define E_FILENOTFOUND 1000
int SomeFunction()
{
// Assume something happens in this f(x)
// that causes the following return value.
return E_FILENOTFOUND;
}
void main()
{
int retVal = SomeFunction();
if(retVal == E_FILENOTFOUND)
printf("Cannot find file...");
}

 This method is not a self describing agent.


193
The Role of .NET Exception Handling

 Structured Exception Handling(SEH)


 This provides a way to encapsulate the name,message, and other
helpful info regarding the error condition into a single structured
package.
 The beauty of this approach is that developers now have a unified
approach to error handling,which is common to all languages targeting
the .NET universe.
 Another advantage of .NET exceptions is the fact that rather than
receiving a cryptic numerical value that identifies the problem at hand,
exceptions are objects that contain a human-readable description of
the problem, as well as a detailed snapshot of the call stack that
triggered the exception .
194
The atoms of .NET Exceptions

 Programming with structured exception handling


involves the use of four interrelated entities:
 A class type that represents the details of the exception
that occurred
 A member that throws an instance of the exception class
to the caller
 A block of code that will invoke the exception-ready
method
 A block of code that will process or catch the exception
195
System.Exception Base Class

 In C# , exceptions are represented by a class.


 All Exception classes must be derived from the built
in exception class exception.
 From exception class are derived
 System Exception and Application Exception.
 Most of the memebers defined by System.Exception
are read-only

196
System.Exception Base Class

Property Meaning
HelpLink This property returns a URL to a help file describing
the error in full detail.
InnerException details of previous exceptions that caused the
current exception
Message returns the text message describing the error
Source name of the assembly that threw the exception

StackTrace sequence of calls that triggered the exception

TargetSite returns a MethodBase type, which describes numerous


details about the method that threw the exception
197
Throwing a Generic Exception

public void Accelerate(int delta)


{
if (carIsDead)
Console.WriteLine("{0} is out of order...", petName);
else
{
currSpeed += delta;
if (currSpeed > maxSpeed)
{
Console.WriteLine("{0} has overheated!", petName);
currSpeed = 0;
carIsDead = true;
}
else
Console.WriteLine("=> CurrSpeed = {0}", currSpeed);
}
}

198
Throwing a Generic Exception

public void Accelerate(int delta)


{ if (carIsDead)
Console.WriteLine("{0} is out of order...", petName);
else
{
currSpeed += delta;
if (currSpeed >= maxSpeed)
{
carIsDead = true;
currSpeed = 0;
// Use "throw" keyword to raise an exception.
throw new Exception(string.Format("{0} has overheated!", petName));
}
else
Console.WriteLine("=> CurrSpeed = {0}", currSpeed);
}

199
Catching Exceptions
static void Main(string[] args)
{
Console.WriteLine("***** Creating a car and stepping on it *****");
Car myCar = new Car(“Swift", 20);
try // Speed up past the car's max speed to trigger the exception.
{
for(int i = 0; i < 10; i++)
myCar. Accelerate(10);
}
catch(Exception e)
{
Console.WriteLine("\n*** Error! ***");
Console.WriteLine("Method: {0}", e.TargetSite);
Console.WriteLine("Message: {0}", e.Message);
Console.WriteLine("Source: {0}", e.Source);
}
// The error has been handled, processing continues with the next statement.
Console.WriteLine("\n***** Out of exception logic *****");
} 200
.NET Exceptions …
 The CLR supports an exception handling model based on the
concepts of exception objects and protected blocks of code
 The runtime creates an object to represent an exception when
it occurs. You can also create your own exception classes by
deriving classes from the appropriate base exception
 Each language uses a form of try/catch/finally structured
exception handling

201
Why Exceptions?
 Code that uses exceptions are clearer and more robust than
other methods
bool RemoveFromAccount(string AcctID, decimal Amount)
{
bool Exists = VerifyAmount(AcctID);
if (Exists)
{
bool CanWithDraw = CheckAv(AcctID, Amount);
if (CanWithDraw)
{ return WithDraw(AcctID, Amount); }
}
return false;
}

202
Disadvantages of
Traditional Methods
 Code that depends on return value – must provide additional
error parameters or call other functions (e.g. Win32 API)
 Returning error code – must be handled properly
 Error codes are difficult to extend and update. The entire
source code must be updated for any new error codes
 C# uses rich Exception object which contains info about
failure condition

203
Handling Exceptions
 To handle an exception you must protect with a try block and
have at least one catch block
try
{
Employee e;
e.GiveBonus(); // null reference
}
catch
{
// Handle any exception
}

204
How Exceptions are Executed?
 To catch an exception the try-catch block must be used
 A try block is a section of the code that looks for an exception
 When an exception is raised, or thrown, within a try block, an exception object
is created and a search begins in the catch block
 When an exception occurs within that scope, the control goes to the
appropriate catch block (handler)
 If no exception occurs, obviously the catch block is never executed
 After the catch block code is executed the rest of the code in the program
continues (is it OK?)
 Catch block can also rethrow the exception

205
Catching
try
Specific Exceptions
{
Employee e;
e.GiveBonus(); // null reference
}
catch (NullReferenceException ex)
{
// Log the error
throw(ex);
}
 If the catch block can recover from the error that caused the exception, execution can
continue after catch block. If it can't, then it must rethrow (shown in red color).
 If an exception is rethrown, the next catch block will be checked. The check may
continue in the call stack until a proper handler is found. If none found, terminate!

206
throw statement
 The throw statement is used to signal the occurrence of an
anomalous situation /exception and to send the error object
back to the caller (raising an exception)
 throw [expression];
expression is an exception object
 Usually the throw statement is used with try-catch or try-finally
statements. When an exception is thrown, the program looks
for the catch statement that handles this exception

207
Example
using System;
(throw)
public class ThrowTest
{
public static void Main()
{
Output:
string s = null; The following exception occurs:
if (s == null) System.ArgumentNullException
{
throw(new ArgumentNullException());
}
// not executed
Console.Write("The string s is null");
}
}
208
Example (try - catch)
using System;
class AddInts
{
static void Main(string[] args)
{
int a, b;
int c, d = 0;

Console.Write("Enter the first number (a): ");


a = System.Int32.Parse(Console.ReadLine());

Console.Write("Enter the second number (b): ");


b = System.Int32.Parse(Console.ReadLine());

c = a + b;

209
try
{
d = a / b;
}
catch(Exception e)
{
Console.WriteLine("Method: {0}", e.TargetSite);
Console.WriteLine("Message: {0}", e.Message);
Console.WriteLine("Source: {0}", e.Source);
return;
}
Console.WriteLine("a + b = {0}", c);
Console.WriteLine("a / b = {0}", d);
}
}

Enter the first number (a): 29


Enter the second number (b): 0
Method: Void Main(System.String[]) //which method threw the exception
Message: Attempted to divide by zero.
Source: AddInts 210
System.Exception Base Class
 Most of the memebers defined by System.Exception are
read-only

Property Meaning
HelpLink URL to a help file
InnerException details of previous exceptions that caused the
current exception
Message returns the text describing the error
Source name of the assembly that threw the exception

StackTrace sequence of calls that triggered the exception

TargetSite returns the MethodBase type


211
Example-2 : StackTrace
 StackTrace: Displays sequence of calls that resulted in
throwing the exception. We can follow the flow of the error's
origin
catch(Exception e)
{
Console.WriteLine("Stack: {0}",e.StackTrace);
}

212
Example-3
try
: HelpLink
{
// create a new Exception object, passing a string
Exception myException = new Exception("myException");
// set the HelpLink and Source properties
myException.HelpLink = "See the Readme.txt file";
myException.Source = "My HelpLink Program";
// throw the Exception object
throw myException;
}
catch (Exception e)
{
// display the exception object's properties
Console.WriteLine("HelpLink = " + e.HelpLink);
Console.WriteLine("Source = " + e.Source);

HelpLink = See the Readme.txt file


Source = My HelpLink 213
Building Custom Exceptions
 Though the System level exceptions are useful,
sometimes it is necessary to build user defined
exceptions
 Define a new user defined class derived from
System.Exception
 You may override any virtual members defined in the
parent class

214
Square
۩ using System;
Root
namespace CustomException
{
class NegNumException : ApplicationException
{
class NegNumException : ApplicationException
{
public NegNumException()
: base("SNG: Negative Number Exception")
{}
public NegNumException(string msg)
: base(msg)
{}
public NegNumException(string msg, Exception inner)
: base(msg, inner)
{}
} 215
Square Root…
class CustomException
{
public double SqRoot(double n)
{
if (n < 0)
// calls 1-arg ctor.
// throw new NegNumException
("SNG: Negative Number not allowed");
// calls default ctor.
throw new NegNumException();
return Math.Sqrt(n);
}

216
Square Root…
public void SqRootTest()
{
double n;
try
{
Console.Write("Enter a number: ");
n = System.Double.Parse(Console.ReadLine());
double result = SqRoot(n);
Console.WriteLine("Sq Root = {0}", result);
}
catch(FormatException ex)
{
Console.WriteLine(ex.Message);
}
catch(NegNumException ex)
{
Console.WriteLine(ex.Message);
}
}
217
Square Root…
static void Main(string[] args)
{
CustomException e = new CustomException();
e.SqRootTest();
}
}
}

218
Multiple Exceptions
 The code in the try block may trigger more than one exception.
 Under these circumstances you can have more than one catch
block
 Exception will be processed by the nearest available catch
block (Below example is wrong!)
 Ex: try { … }
catch (Exception e) {…}
catch (NegNumException e) {…}
catch (ArgumentOutOfRangeException e) {…}

Unreachable
219
Other types of Exception Handling
 Generic catch
try {…} No argument
catch
{…}
 Rethrowing Exceptions
try {…}
catch (NegNumException e)
{
// handle the error and pass the buck
throw e;
} rethrow the same
exception
 The finally Block
- The optional finally block will get executed always
- Useful for cleaning up process or close the database files

220
Garbage Collection
 C# Programmers never directly deallocate an object from memory – so no
'delete' keyword
 Rule: Allocate an object on to a managed heap using ' new' and forget about it!
 How does .NET determine that an object is no longer needed? When it is
unreachable by the current application
 Example:
public static int Main(string[] args)
{
Car c = new Car( );
….
} When the
application shuts
down, object c may
be destroyed.
221
Garbage Collector
 CIL emits newobj for new
 .NET garbage collector maintains a new object pointer which
indicates where the next object should be placed in the heap
 Assume c1, c2, and c3 are objects of type Car

c3 c2 c1 Unused heap
next object pointer

222

Garbage Collector…
If the managed heap does not have enough memory, CLR does garbage
collection. It frees the memory to accommodate the new object
 Which object memory is to be removed – "no longer needed" basis
 Objects that have been recently allocated are most likely to be freed
 Objects that have lived the longest are least likely to be become free
 Objects allocated together will be used together
 To get this idea CLR uses an object graph to know whether the objects are
still in use.
 The other objects which are no longer used – "severed roots" or unreachable
objects are reclaimed and the memory is compacted with necessary object
pointer adjustment

223
Garbage Collector…
 The Garbage Collector in .NET is known as generational garbage
collector.
 Allocated objects are sorted into three groups or generations:
 generation 0: objects allocated most recently
 generation 1: Objects that survive a garbage collection pass are
moved into generation 1
 generation 2: Objects that survive in generation 1 are moved into
generation 2
 If no memory is available after compaction, an
OutOfMemoryException is thrown

224
 Finalizing a Type
The garbage collection process is nondeterministic
 To release the memory in a timely manner, one possible solution is to override
System.Object.Finalize() method.
 We go for this only when C# types are using unmanaged types (Win32 APIs) Unmanaged
resources: database connections and GDI
 Note that you can't override this method directly:
public class FinalizedCar
{
protected override void Finalize() { } // Wrong
}
 protected void Finalize() // don't expose this method
{
base.Finalize();
}
 Do not define both a destructor and Finalize method in the same class

225

Indirectly Invoking Finalize()
When an Application domain is unloaded by CLR, the Finalize() method is invoked for all
finalizable objects
class FinalizedCar
{
~FinalizedCar()
{ Console.WriteLine("Finalizing"); } // 3
class FinalizeApp
{
static void Main(string[] args)
{
Console.WriteLine("Object creation"); // 1
FinalizedCar fc = new FinalizedCar();
Console.WriteLine("Exiting Main"); // 2
}
}
}

 Instead of using a finalizer (because it is costly), you can expose the Dispose() method
226

Dispose with using
With the presence of the using statement, which opens a scope at the end of
which a given object will be disposed, regardless of whether the scope is
exited normally or via an exception.
using( Pen myPen = new Pen(Color.Red) )
{
// Do stuff with myPen
}
 When objects are of the same type, you may put them all inside the same
using statement:
using( Pen myRedPen = new Pen(Color.Red),
myBluePen = new Pen(Color.Blue) )
{
// Do stuff with both pens
}

227
 Dispose with
For instance, you'll need a Font andusing
a Brush if you want to use the Graphics.DrawString method
to paint some text. Unfortunately, here's where the using statement starts to break down,
because the following code generates a compile error:
using( Font myFont = new Font("Arial", 16),
SolidBrush myBrush = new SolidBrush(Color.Blue) )
{
// COMPILE ERROR!
}
 That snippet doesn't compile because C# doesn't let you have more than one type in a single
using statement. So, your next alternative is to nest using statements like this:
using( Font myFont = new Font("Arial", 16) )
{
using( SolidBrush myBrush = new SolidBrush(Color.Blue) )
{
{
// Do stuff with a font and a brush
}
}
}

228
Dispose with using
 But use of more than a couple of levels of nesting,
and your code gets ugly pretty quickly
 Hence, we must search for a better
solution………………..

229
Implementing IDisposable
 Creating and properly disposing of an object requires several
lines of correctly written code.
 C# provides an automated solution based on IDispose interface
 IDispose interface provided in .NET is for symmetry among all
objects that supports an explicit destruction

230
IDispose Implementation Flow

231
Implementing
public class MyClass : IDisposable
IDisposable…
{
public void Dispose()
{
Console.WriteLine("Custom cleaning process");
}
}

public class IDisposeApp


{
public static void Main(string[] args)
{
MyClass m = new MyClass();
m.Dispose();
}
}

232
Example
public class ClassBeingTested : IDisposable
{
private bool disposed=false;
private Image img=null;
public Image Image
{
get {return img;}
}
// the constructor
public ClassBeingTested()
{
Trace.WriteLine("ClassBeingTested: Constructor");
}
// the destructor
~ClassBeingTested()
{
Trace.WriteLine("ClassBeingTested: Destructor");
// call Dispose with false. Since we're in the
// destructor call, the managed resources will be
// disposed of anyways.
Dispose(false);
}
233
public void Dispose()
{
Trace.WriteLine("ClassBeingTested: Dispose");
// dispose of the managed and unmanaged resources
Dispose(true);

// tell the GC that the Finalize process no longer needs


// to be run for this object.
GC.SuppressFinalize(this);
}

234
protected virtual void Dispose(bool disposeManagedResources)
{

// process only if mananged and unmanaged resources have not been disposed of.
if (!this.disposed)
{
Trace.WriteLine("ClassBeingTested: Resources not disposed");
if (disposeManagedResources)
{
Trace.WriteLine("ClassBeingTested: Disposing managed resources");
// dispose managed resources
if (img != null)
{
img.Dispose();
img=null;
}
}
// dispose unmanaged resources
Trace.WriteLine("ClassBeingTested: Disposing unmanaged resouces");
disposed=true;
}
else
{
Trace.WriteLine("ClassBeingTested: Resources already disposed");
}
}

235
End of Chapter - 5
 For more details on IDispose implementation, please
refer to:
 www.codeproject.com/csharp/IDispose.asp
 C# How to Program by DEITEL & DEITEL

236
237

Você também pode gostar