Escolar Documentos
Profissional Documentos
Cultura Documentos
.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
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#
Visual Studio.NET
ASP.NET Windows
Web Forms Web Services Forms
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.
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 }
{ }
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
18
CIL to Execution
Desktop
Pocket PC
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; }
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
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
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
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)
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;
}
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
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
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();
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
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
86
UnBoxing
Converting the value in an object reference (held in heap) into
the corresponding value type (stack)
UseThisObject(myInt);
Console.ReadLine();
}
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
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.
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
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
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
{
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;
}
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
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");
131
String Manipulations in C#
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
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;
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;}
}
}
}
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
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
176
More Details: (3) Polymorphism
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 }
}
182
Method Hiding
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
}
184
End of
Chapter 4
185
Chapter - 5
Exceptions
and
Object Lifetime
186
Chapter Objectives
188
Definitions for three commonly used anomaly-centric terms:
189
Definitions for three commonly used anomaly-centric terms:
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
192
The Role of .NET Exception Handling
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
198
Throwing a Generic Exception
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;
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);
}
}
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
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);
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");
}
}
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);
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