overview of net n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Overview of .NET PowerPoint Presentation
Download Presentation
Overview of .NET

Loading in 2 Seconds...

play fullscreen
1 / 180

Overview of .NET - PowerPoint PPT Presentation


  • 66 Views
  • Uploaded on

Overview of .NET. Essential features C++ replaced by C# Simplify software development a new component model Simplify software upgrade Web services Simplify distributed computing. C#. The core language used in .NET Similar to Java, some features from C++ Main features

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Overview of .NET' - zelda-pierce


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
overview of net
Overview of .NET
  • Essential features
    • C++ replaced by C#
      • Simplify software development
    • a new component model
      • Simplify software upgrade
    • Web services
      • Simplify distributed computing
slide2
C#
  • The core language used in .NET
  • Similar to Java, some features from C++
  • Main features
    • C-pointer replaced by reference (no more *, &, ->)
    • User-defined type (class and object)
    • Managed heap (system deletes memory for you)
    • Extensive class library
      • (ADO.NET, ASP.NET, DirectX, Web Service)

Java

C++

C

C#

what is a component
What is a component?
  • A component is a binary module that can be shared
  • Important to developers because
    • No need to release the source code to public
    • Upgrade can be done by replacing an old component with a new one at binary level

System

Component

dll dynamic link library before net
DLL (Dynamic Link Library) before .NET
  • Evolution of DLL
    • In C era, DLL is a library of shared functions
    • In C++ era, DLL is a binary component known as COM, which consists of a collection of objects
  • Problem
    • If an existing COM is replaced by a new one, the addresses of the functions will be changed
    • How to find the new addresses in the new COM without re-link the entire system?
the problem with binary component replacement
The problem with binary component replacement

Old component

1234 foo()

Old System

Exec foo(), jump to address 1234

where is foo
Where is foo()?
  • Address of foo() is changed in new component
  • Old system doesn’t know about it and we do not want to relink the entire system
  • New component
  • xxx
  • foo()

Old System

Exec foo(), jump to address 1234

com s solution
COM’s solution

Old System

Exec foo(),

- Get IUnknown

- Call QueryInterface()

- jump to new address

  • New component
  • xxx
  • foo()

IUnknown

QueryInterface()

com way
COM way
  • Lookup table approach
    • Get the IUnknown pointer from a known address in the new component
    • IUnknown points to a lookup table has a pointer to a function called QueryInterface()
    • Use this function to query the new addresses of the functions/objects
  • Convenient from the user point of view
  • Tedious from the developer point of view
    • A lot of extra coding
dll hell
DLL Hell
  • Install a new software that uses a ver 2.0 component that
    • The component is shared by many other software
    • Windows supports only one version
      • ver 1.0 COM is replaced by ver 2.0
    • Other software are FORCED to use ver2.0 component
    • But these program were tested using ver1.0
    • ver2.0 should be backward compatible with ver1.0
      • Backward compatibility is difficult to do in practice
    • Software may break
  • The problem caused by replacing the old DLL with new DLL is known as DLL hell
net solution
.NET solution
  • COM programming is complex, needs to manipulate the IUnknown pointer; we also have DLL hell
  • .NET
    • CLR – Common Language Run-time
      • Virtual machine approach (like Java’s JVM)
    • Source code (C#, VB, etc) are complied into byte code called MSIL (Microsoft Intermediate Language)
    • Byte code is mapped to executable code when it is loaded to the machine
    • CLR converts byte code to executable code, and fills in the actual physical addresses
net solution1
.NET solution
  • Pros
    • The byte code is abstract, and can be run on any platform
    • Because we are dealing with meta-code, CLR has the full information to resolve unknown addresses
      • the COM’s style of programming is obsolete
    • Multiple versions, side-by-side execution
      • .NET supports multiple versions, no more DLL hell
  • Con
    • Need to convert byte-code at loading time, therefore slower response
overview of net1

Common Language Runtime (CLR)

Common Type System

Common Language Spec

Overview of .NET

C#

VB

C++

Perl

Python

Cobol

Smalltalk

Class Library

ADO.NET GUI XML/SOAP DirectX etc

advantages of net simplification
Advantages of .NET - simplification
  • Interesting features
    • Language interoperability
      • Can mix VB with C#, or any combinations !!
      • Because all languages are compiled into the same intermediate language (MSIL) code
    • Software distribution is much simplified
      • Resolving address references is done by CLR
      • The support of multiple versions
    • Hugh class libraries
slide14
Common Language Runtime (CLR)
    • Provides the environment to support multiple languages, simplifies deployment and management
    • Loader, Just-in-time compiler, garbage collection, security, debugger, type checker, thread support, …
  • Common Type System (CTS)
    • Define the data types and programming constructs supported by the CLR
  • Common Language Specification (CLS)
    • A subset of CTS that all .NET languages must agree upon, so as to support language integration (e.g. mixing of VB and C#)
similarity with java
Similarity with Java
  • Both environment are supported by virtual machine
    • In Java – the Java Virtual Machine (JVM)
    • In .Net – CLR
  • Java Platform, Enterprise Edition (JEE)
    • One language, multiple platforms
  • .NET
    • One platform, multiple languages
  • Open source .NET platform
    • Mono, DotGNU – both runs on Linux
    • C# is an open standard (!!)
jee vs net vs lamp
JEE vs .NET vs LAMP
  • JEE
    • Pro: system interoperability, can sells Java applications to many different platforms
    • Con: complex
  • .NET
    • Pro: support multiple languages integration
    • Con: MS platform (unless Mono provides real alternative)
  • LAMP (Linux/Apache/MySql/Perl/Python/PHP)
    • Pro: free
    • Con: open source, lack of support
compile and run simple c program
Compile and run simple C# program

using System;

class HelloWorld

{

public static void Main()

{

Console.WriteLine(“Hello C# world”);

}

}

  • Save: Hello.cs
  • Compile: csc Hello.cs
  • Run: Hello
output options of compiler
Output options of compiler
  • csc -?
    • Shows you the list of output options
  • csc /t:exe Hello.cs
    • Output: Hello.exe application, the default
  • csc /t:library Hello.cs
    • Output: Hello.dll assembly(a library component)
  • What is an assembly?
    • The basic unit of a binary file in .NET
    • Byte code from a single or multiple source files
gui version of hello c world
GUI version of “Hello c# world”

using System;

using System.Windows.Forms; //using the GUI library

class HelloWorld

{

public static void Main()

{

MessageBox.Show("Hello c# world"); //a GUI box

}

}

  • Save as : HelloBox.cs
  • Compile: csc HelloBox.cs
  • Run: HelloBox
  • Display a box containing the message “Hello c# world”
multiple source files
HelloApp.cs

using System;

class HelloWorld

{

public static void Main()

{

HelloMsg obj =

new HelloMsg();

obj.Write();

}

}

HelloMsg.cs

using System;

using System.Windows.Forms;

public class HelloMsg

{

public void Write()

{

MessageBox.Show

("Hello c# world");

}

}

Multiple source files

Compile: csc HelloApp.cs HelloMsg.csRun: HelloApp

to make a sharable component
To make a sharable component
  • To make HelloMsg.dll a sharable component
    • csc /t:library HelloMsg.cs
  • To link the component with the main program HelloApp.cs
    • csc /r:HelloMsg.dll HelloApp.cs
  • Run: HelloApp
deployment
Deployment
  • To distribute software under .NET is a huge simplification compared to COM
    • Just copy the assembly files and distribute !
  • To distribute a shared component is only slightly more complicated
    • Make the component a strong-name assembly
    • Add the assembly to Global Assembly Cache (GAC) so that it can be shared

gacutil.exe /if HelloMsg.dll

  • Strong-name assembly uses public key cryptography to ensure authenticity (code is from the originator) and integrity (code has not been modified)
strong named assembly
Strong-Named Assembly
  • Generate a public-private key pair

sn –k myKey.snk

  • Add code to source file to specify version and key info

#if STRONG

[assembly: System.Reflection.AssemblyVersion(“1.0.0.0”)]

[assembly: System.Reflection.AssemblyKeyFile(“myKey.snk”)]

#endif

  • Compile

csc /define:STRONG /t:library /out:HelloMsg.dll HelloMsg.cs

to protect the authenticity and integrity of the assembly
To protect the authenticity and integrity of the assembly
  • The pair of private and public keys
    • Locked (encrypted) the data by public key, unlocked by private key, or
    • Locked (encrypted) the data by private key, unlocked by public key
  • Private key is secret, public key is well known (contained in a digital certificate, published on Internet)
  • Hash the assembly and the public key into a hash code
  • Encrypted the hash code by the private key
  • Distribute the assembly, the public key and the encrypted hash code
slide25

Distributed code

Locked by private Key

Assembly+public key

Hashed Assembly+public key

Unlocked by

public key

Hashed

Hashed Assembly+public key

Same?

Hashed Assembly+public key

authenticity and integrity check
Authenticity and integrity check

1) Decrypted the hash code using the public key

2) Hash the assembly and the public key

  • If the results are the same, then
    • “assembly+public” has not been changed
      • Otherwise the two hash codes will be different
      • pass integrity check
    • The public key is the right key in decrypting the hash key
      • Can check the authenticity of the public key from digital certificate
slide27
Main()
  • *.exe must contains a Main() function
  • Different versions of Main()
    • public static void Main()
      • No input argument, no return value
    • public static void Main(string[] args)
      • Input arguments in a string array
    • public static int Main(string[] args)
      • Input in a string array, return an integer
class and object
Class and object
  • A class is a definition of a user-definedtype (UDT)
    • Defines the variables and the methods
    • Does not take up memory
  • An object is an instance of a class
    • Takes up memory
  • Example
    • int x;

Type

Instance

class and object1
Class and object
  • intx = 10;
  • Invokes a construction int() to create an object called x
    • Data is localized and encapsulated
    • Information hiding, internal representation of the object is separated from outside, can change the object, e.g. number of bits per integer, (but not the methods (interface!)) without affecting the rest of the system

x

10

INTERFACE

+

-

*

/

int()

class and object2
Class and object
  • int is a system defined type
  • A class has
    • Attributes
      • The data in the object
    • Methods
      • The functions that can be used by the object
    • Constructors
      • Functions for creating the object
      • Constructor has the same name as the class
  • Use the class keyword to define your own type
example
Example

public class Student {

private int ID;

private string name;

public Student(int ID, string name) {

this.ID = ID;

this.name = name;

}

public string getName() {

return name;

}

}

attribute

constructor

method

slide32
The class has
    • two attributes (ID and name)
    • a constructor Student()
    • a method getName()
  • private means the thingy can be accessed (seen) only by methods within the class
  • Principle of encapsulation
    • methods should be public, attributes should be private
    • Since attributes are hidden, they can be changed freely (loose coupling)
constructor student
Constructor Student()
  • Create a Student object
    • Student s = new Student(7,”James Bond”);
  • Constructor Student() has the same name as the class
    • s is a reference (pointer) located in the stack which points to the object located in the heap

Type

constructor

A reference to

the object

function overloading
Function overloading
  • Overloading means different functions can have the same name, as long as their signatures are different
    • Signature = parameter list
  • e.g. constructors with same name but different signatures
    • public Student() {…}

public Student(int ID, string name){…}

    • No need to specify the type of the return value, it must be the same as the class (Student)
function overloading1
Function overloading
  • Default constructor – Student()
    • Default constructor takes no argument
    • Members in the object are initialized to their default values (0 for numbers, null for string, false for bool)
  • To redefine the default constructor
    • Write your own !

public Student() {

ID = 0; //default value

name = “unknown”; //default value

}

other ways
Other ways
  • If you have too many similar overloaded constructors, simplify them by the forwarding construct
  • public Student(string name) : this(0, name){}
  • public Student(int ID) : this(ID,”unknown”){}
  • Call is forwarded to
    • Student(int ID, string name)
constructor
Constructor
  • Class is like a stamp that produces many objects
  • Each object has its own set of attributes
  • e.g. 2 Student objects created by constructor Student()
    • Student s1 = new Student(7,“James Bond”);

Student s2 = new Student(8,“Goldfinger”);

s1

s2

8

Goldfinger

7

James Bond

object identity and this
Object identity and “this”
  • Object is uniquely identified by a reference pointer (e.g. s1, s2)
  • The reference pointer is used to uniquely identify a function or an attribute
    • e.g. s1.name, s2.getname()
  • When an object refers to its own attributes or functions, you can use the “this” pointer instead of the specific reference pointer
    • e.g. this.name
slide39
“this”
  • Console.WriteLine(“name={0}”,s1.getName());
  • s1.getName() invokes s1’s function getName()
    • The getName() in object s1 is called
    • The reference s1 is passed implicitly as the “this” pointer in getName()
  • public string getName() {

return this.name; //return name; also OK

}

  • When there is no ambiguity, “this” can be omitted
encapsulation
Encapsulation
  • Don’t expose the details of an object to outside world
    • Why? If this information is used by outside world, you are less free to change the object in future
  • Attributes (data) should not be exposed (encapsulated)
    • private (the default)
    • Can only be accessed by members in the object
    • External world can only it via public methods
  • Method
    • private (the default),
    • Set to public mode only if you want to expose it
visibility
Visibility
  • public
    • accessible anywhere
  • private
    • accessible only by the class (not even subclass)
  • protected
    • accessible by the class and its subclass
  • internal
    • accessible only within an assembly
  • protected internal
    • accessibly within assembly or the subclass
example of visibility
public class A {

public void foo() {

B obj = new B();

obj.MethodPublic();

//OK

obj.MethodPrivate();

//Not OK, private

obj.MethodProtected();

//not OK, A is not a subclass of B

obj.MethodInternal();

//OK if A and B are in

same assembly

}

}

public class B {

public void MethodPublic(){}

private void MethodPrivate(){}

protected void MethodProtected(){}

internal void MethodInternal(){}

}

Example of visibility
type class visibility
Type (class) visibility
  • class also has visibility control
    • public or internal
    • Default is internal (if you don’t specify anything)
  • General rule
    • If you don’t specify the visibility explicitly, the default visibility is always the most restricted one
    • Method -> private
    • class-> internal
static method
Static method
  • Methods are usually at the object level
    • Need an object to invoke the method
    • e.g. s1.getName();
  • Exception - static method
    • class level method, only one method per class
    • Unique, invoke using the class name instead of object
      • Convenient, the main reason of using static method
    • Not associated with any object, therefore cannot access attributes in an object
    • e.g. Console.WriteLine(“hello”);

//WriteLine() is a static method in class Console

static data
Static data
  • Class level data (instead of object level data)
  • Unique (one and only one) copy of data per class
    • All objects in the same class share the static data
    • No ambiguity, can be accessed directly using the class name
    • e.g. Student.typename

class Student {

static private string typename= “Student”;

. . .

}

class level and object level s method data
Class level and object level’s method/data
  • Class A {

static public void foo();

static private int x;

public void bar();

private int y;

}

A object1 = new A();

A object2 = new A();

A object3 = new A();

class level and object level s method data1
Class level and object level’s method/data

Class level method/data

Only one copy

No need to identify the object

e.g. A.x, A.foo()

Class A

int x

foo()

object1

object2

object3

Object level method/data

Many copies

Need to identify the object

e.g. object1.bar()

int y

bar();

int y

bar();

int y

bar();

property
Property
  • Data is usually private,retrieved only by public method
    • e.g. read by getXXX(); updated by setXXX()
    • Tedious, property provides a short-cut
  • public class Student {

string name;

public string Name {

get {return name;}

set {name = value;}

}

main() {

Student s = new Student(7,”James Bond”);

s.Name = “Goldfinger”; //replace setName()

Console.WriteLine(“name is {0}”,s.Name);

}

c reference
C# reference
  • C/C++ pointer is error prone
    • int a=10; int *p; //p is a pointer

p = &a; //p is the address of ‘a’

*p=20; //*p=a, deferencing

  • Pointer powerful but is also a major source of bugs
    • It can be used in two ways (address vs value)
    • p = the address of the data
    • *p = the data
c reference1
C# reference
  • We almost always use the pointer to obtain the value
  • Seldom use pointer to refer to the address of the value
  • C# and Java reference
    • a pointer that only refers to the value
    • Therefore can drop the *
    • i.e. an automaticdeferencingpointer without the *
    • Less powerful, but also less bugs
  • Can’t refer to the address of a variable in C#
    • Unless in “unsafe” mode
memory allocation stack and heap
Memory allocation - stack and heap
  • Memory for the variables are allocated either in the stack or in the heap
  • In the stack
    • Size of the variable is known at compilation time
      • e.g. primitives – char, int, double, structure
  • In the heap
    • Size of the type can be changed at run-time, therefore it is not known at compilation time
    • e.g. array, objects created at run-time by constructors
stack and heap
Stack and heap

.exe file

i (4 bytes)

f (8 bytes)

s(4 bytes)

empty space

Student object

void foo(int i) {

double f;

Student s = new Student();

}

  • Stack grows downward
  • Heap grows upward

stack

Current stack pointer

heap

stack
Stack

.exe file

i (4 bytes)

f (8 bytes)

s(4 bytes)

i (4 bytes)

f (8 bytes)

s(4 bytes)

  • Stack grows downward
  • Supports recursion

void foo(int i) {

double f;

Student s=new Student(…);

i--;

if i!=0 foo(i);

}

1st call

2nd call

Call foo() until i=0

memory management in the stack
Memory management in the stack
  • Memory in the stack is freed automatically
  • For local variables
    • Whenever the variable is out of scope (function returns to caller), stack pointer moves upward
    • Memory under the stack pointer is freed automatically
  • For global variables (static)
    • Memory is allocated at the top of the stack
    • Freed automatically when the program is terminated
memory management in the heap
Memory management in the heap
  • Memory in the heap must be freed explicitly
  • C/C++
    • User is responsible in freeing the memory
    • Forgot to free the memory?
      • memory leak, system will run out of memory
  • C# and Java
    • Heap’s memory is freed automatically by Garbage Collector
    • Less chance for error
garbage collector algorithm
Garbage collector algorithm
  • Objects are stored in the heap, how to free them?
  • Object is always addressed by a reference pointer, which is stored in the stack
  • Build an object graph from references in the stack, if an object is not connected to any reference, then the object can be deleted
  • When to carry out this garbage collection process?
    • A slow process, only do it when the system runs out of memory
object graph
Object graph

Object in heap

Stack

A Student object

A String object

ID

name

s1

James Bond

Goldfinger

ID

name

Unconnected object

will be deleted by

the garbage collector

parameter passing in c
Parameter passing in C#
  • The default is to pass parameter by value
    • Same as C

public static void Main() {

int x=10;

foo(x);

Console.WriteLine(“x={0}”, x); //x=10

}

public static void foo(x) {

x=20; //x in Main()is not affected

}

Pass by value

pass by value
Pass by value
  • A copy of x is passed via the stack
  • Pass by value is safe because the caller’s state is not affected by calling an unknown function

Stack

Main’s x

10

10

Copy of x passed to foo()

pass reference by value is more subtle
Pass reference by value is more subtle
  • What if we pass a references to bar(s)?

public static void Main() {

Student s = new Student(7,”James Bond));

bar(s);

Console.WriteLine(“name={0}”,s.getName());

}

public static void bar(Student s) {

s.setName(“GoldFinger”);

}

name changed to GoldFinger!

pass reference by value
Pass reference by value
  • The name in object s is changed by bar(s) to Goldfiner
    • A copy of the reference is passed by value via the stack
    • Both references point to the same object in heap!
    • bar(s) changes the state of s in Main

Main’s s

FF0000

FF0000

Copy of s passed to bar()

James Bond

why this time bar has no effect on the name of s
Why this time bar() has no effect on the name of s?

public static void Main() {

Student s = new Student(7,”James Bond));

bar(s);

Console.WriteLine(“name={0}”,s.getName());

}

public static void bar(Student s) {

s = new Student(8,”Goldfinger”);

}

This time name is still James Bond

s points to a new object

pass reference by value1
Pass reference by value
  • Initially a copy of the reference is passed by value via the stack

FF0000

Main’s s

FF0000

James Bond

bar()’s

FF0000

pass reference by value2
Pass reference by value
  • public static void bar(Student s) {

s = new Student(8,”Goldfinger”);

}

  • s in bar() points to a newly created object

FF0000

Main’s s

FF0000

James Bond

bar()’s

FF0010

FF0010

Goldfinger

c parameter modifiers in out ref params
C# parameter modifiers - in, out, ref, params
  • in
    • Parameter is passed by value, the default
  • out
    • Use out to return several values (this overcomes the limitation of return value)
    • public void foo(int x, out int a, out string s)
    • out keyword must also be specified by the caller
    • main() {

int x=0; int a; string str;

foo(x, out a, out str);

}

slide66
ref
  • Pass value type by reference, if you really want data in the caller’s scope be modified by the method
    • This is similar to passing an address, but still you don’t need to dereference using *
  • main() {

int x=10; int y=20;

swap(ref x, ref y);

Console.WriteLine(“x={0},y={1}”,x,y);

}

public static void swap(ref int x, ref int y){

int temp;

temp=x; x=y; y=temp;

}

params
params
  • To pass a varied number of parameters as a single argument
    • e.g. like the printf() in C
  • main() {

Student s1=new Student(007,”James Bond”);

Student s2=new Student(008,”Goldfinger”);

foo(s1, s2); //s1,s2 pass as params list

}

public static void foo(params Student[] list){

foreach (Student s in list)

Console.WriteLine(“name={0}},s.getName());

}

key concepts in oo
Key concepts in OO
  • Encapsulation
  • Inheritance
  • Polymorphism
  • Delegation
key concepts in oo1
Key conceptsin OO
  • How to develop software quickly and cheaply
    • Reuse code as much as possible
  • But other people’s code takes time to learn
  • To make our code easier for other to use, we must
    • provide a simplified picture of our code
      • Abstraction
    • hide away the complexity
      • Encapsulation
global data versus local data
Global data versus local data
  • Code includes methods and data
  • To reuse code, data must be readily available
  • Non-OO languages, no restriction on the location of data
    • Data can be any where
  • OO languages, data is localized
    • data is within the object, simplifies reuse
    • Object therefore has data, and the methods that operate with the data

Data

Method

inheritance
Inheritance
  • A problem with code reuse
    • Would like to reuse a class, but
      • some methods are not exactly what we want and need to be modified
      • Need to add some more methods
  • Solution
    • Inherit the class (takes everything in the class)
    • Override the methods we want to modify
    • Add new methods
syntax of inheritance
Syntax of inheritance
  • public class A {

private int a;

virtual public void foo();

}

  • public B : A {

virtual public void foo(); //override

virtual public void bar(); //new method

}

  • A is inherited by B, A is the superclass, B is the subclass
  • Only virtual methods can be overrided
visibility1
Visibility
  • Hide the state (private attributes) of an object, exposes the interface (public methods)

class Base {

private int x=0; //nobody can see x except class itself

}

class Derived : Base { //inheritance

public int GetX() {return x;} //NotOK, can’t see x

}

  • A Derived’s object has memory for x because of inheritance, but can’t access it because it is private
encapsulation1
Encapsulation
  • protected – keeping family secret
    • nobody can see it except the class and its child

class Base {

protected int x=0;

}

class Derived : Base {

public int GetX() {return x;} //OK

}

  • public – everybody can access the attribute
    • attributes should never be public
interface and implementation inheritance
Interface and implementation inheritance
  • To reuse an inherited method
    • Implementation reuse
    • Useful but miss the primary use of inheritance
  • The primary use of inheritance is to reuse the Interface
    • Interface inheritance is most important in OO, not implementation inheritance
    • USB is an interface
      • MP3, memory stick, digital camera, etc, are implementations that inherit the interface
key concepts in oo2
Key conceptsin OO
  • Interface is the key to abstraction
  • Users can only see the interface, not the hidden implementation, so that the implementation can be changed freely
  • Different implementations share the same interface
    • One interface, many different implementations
    • Polymorphism
  • All the implementations are based on the interface
    • Implementations inherit the Interface
key concepts in oo3
Key concepts in OO
  • Delegation
    • Some parts in the MP3 player are made by other companies
    • Your MP3 player sends request to the part and asks the part to do some work
      • Delegation to reuse an implementation
  • Delegation and inheritance are the two key ideas in OO
flexible software
Flexible software
  • Requirements always change, your software must also be able to change in future
  • The OPEN-CLOSED PRINCIPLE (Bertrand Meyer)
    • Closed for modification
      • Don’t change existing code
    • Open for extension
      • Add new code to satisfy the new requirements
slide79

Object delegation

New code

(Open for extension)

Your base system (old code)

(CLOSED for modification)

delegation

inheritance

Class inheritance

New Code

(Open for extension)

Class inheritance

New code

(Open for extension)

why existing code should not be changed
Why existing code should not be changed
  • Clients perspective
    • Changes are RISKY, e.g. banks don’t like changes
    • If the old code works, don’t change it
    • Banks are still running 40 years old COBOL programs
  • Developers perspective
    • Changing other people’s code is also difficult
naming convention recommended by msdn
Naming convention recommended by MSDN
  • For public interfaces and properties
    • mark all word boundaries in uppercase
    • PascalCasing
  • For private interfaces and parameters
    • like PascalCasing, except first letter is in lowercase
    • camelCasing
  • Ref: http://dotnet.di.unipi.it/EcmaSpec/PartitionV/cont4.html
example1
Example

_xxx is an

internal parameters

  • public class Base {

private string _name;

public void SetName(string newName) {

_name = newName;

}

}

PascalCasing for

public interface

camelCasing for

parameters

programming to an interface not to an implementation
Programming to an interface, not to an implementation
  • In hardware, USB represents all types of concrete devices (disk, mp3 player, …)
  • In OO, use an interface class Account to represent all types of concrete objects (SavingAccount and CurrentAccount)
  • The rest of the system can only see the base class Account, not the concrete classes
    • As long as the base class is not changed, we can change the concrete class without affecting the rest of the system
is a relationship
IS-A relationship
  • Inheritance is used to model the IS-A relationship
    • SavingAccount is-a specialized type of Account
    • Account is-a generalized type of SavingAccount
  • A bank application has objects from
    • SavingAccount , CurrentAccount, . . .
  • If SavingAccount and CurrentAccount have similar behaviour, how to write a more flexible program?
slide85
class Account {

protected double balance=0;

public virtual void Deposit(double money) {}

}

  • class SavingAccount : Account {

public override void Deposit(double money){

balance = balance + money;

}

}

  • class CurrentAccount : Account {

public override Deposit(double money) {

balance = balance + money;

}

}

oo in one line
OO in one line
  • Account anAccount = new SavingAccount();
oo in one line1
OO in one line
  • Account anAccount = new SavingAccount();

anAccount.Deposit(100); //deposit $100

  • What happens
    • Create a concrete (real) object of type SavingAccount
    • The type of anAccount is casted to Account
    • Rest of the system can only see an Account object, not SavingAccount
  • Why this is good
    • Replace SavingAccount by a newer version, or by CurrentAccount, won’t affect rest of the system
upcasting
Upcasting
  • Technically this is known as upcasting
    • a SavingAccount object is casted to an Account
    • upcasting because books usually draw the base class on top
  • Upcasting is safe
  • Downcasting is dangerous
    • Not allowed unless explicitly say so

SavingAccount anAccount =

(SavingAccount) new Account();

Account

SavingAccount

Explicit casting, should be avoided

why upcasting is safe
Why Upcasting is safe
  • Safe to treat SavingAccount object as an Account object, because SavingAccount supports all methods in Account
    • Implicit upcasting is automatically allowed
  • Downcasting is dangerous
    • Account object is casted into a SavingAccount
    • SavingAccount can have more methods than Account
    • Call a method in SavingAccount, but the concrete object Account may not have it !
    • Downcasting must be explicitly coded, you must know what you are doing
difference between class and type
Difference between class and type
  • Class = interface + implementation
  • Type = interface
  • This distinction is useful because it emphasizes the importance of pure interface inheritance
  • Example
    • Ant is a type of insect, bee is also a type of insect
    • Insect is the base type, it provides only an abstract interface (a generalization of things that have 6 legs)
    • Ant and bee are the sub-types, they provide the concrete implementation
subtyping
Subtyping
  • When to use inheritance
    • To model the relation that “Bis-a subtype of A”
  • This means that
    • B is similar to A
    • B inherits all the interfaces of A
    • What applies to A can also apply to B (but not vice versa because B may have additional interface)
    • We can treat B as if it is A
      • Important, this leads to polymorphism
polymorphism
Polymorphism
  • Subtyping leads to a flexible style of programming
    • Polymorphism
    • SavingAccount, CurrentAccount,etc can be treated uniformly as Account because they share the same interface
polymorphism1
Polymorphism
  • All subtypes of Account can be treated uniformly

Main() {

Account[] accounts = new Account[2]; //array

accounts [0] = new SavingAccount();

accounts [1] = new CurrentAccount();

foreach (Account obj in accounts)

obj.PrintName();

}

  • Output
    • SavingAccount
    • CurrentAccount
why this type of construct is important
Why this type of construct is important?
  • Subtypes SavingAccount and CurrentAccount are both treated as Account
  • Programming on the abstract base class (Account), not on the concrete subclass (SavingAccount, CurrentAccount)
  • Add a new subclass in future (e.g. USDAccount), the rest of the code remains the same (good flexible code)
slide95
Programming the interface, not the implementation
  • Interface is more important that the implementation
    • Easy to replace an implementation (your printer), but not the interface (the printer port is more than 20 years old)
  • Build your system around interfaces

(Account)

(SavingAccount)

pure implementation inheritance
Pure implementation inheritance
  • Inherit the implementation, not the interface
  • public class A {

protected void Foo() {. . .};

}

public class B : A {

public void Bar();

}

  • class A has no public interface
  • class B inherits the implementation of Foo() in A
pure interface inheritance
Pure interface inheritance
  • Inherit the implementation, not the interface
    • C#’s interface cannot have implementation
    • Members are automatically public
  • interface A { //no implementation

void Foo();

}

public class B : A {

public void Foo() { //do something };

public void Bar();

}

abstract class method
Abstract Class / method
  • abstract class is a class that cannot be instantiated
    • abstract public class Account {...}
  • abstract method has no implementation (also known as pure virtual function)
    • A class that has an abstract method are like an abstract class which cannot be instantiated
    • public class Account {

abstract public void Deposit();

}

  • Account f = new Account(); //ERROR
  • Account g = new SavingAccount(); //OK
difference between interface and abstract class method
Difference between Interface and Abstract class / method
  • Abstract base class
    • Cannot be instantiated, but can have implementations
  • Interface
    • Cannot be instantiated, no implementation
    • Its intent is very clear – use it purely for interface inheritance
  • Problem with C++/Java/C# classes
    • Mixed interface with implementation
static versus run time binding
Static versus run-time binding
  • public class Account {

public string GetName(){}; //non-virtual

public virtual void Deposit(); //virtual}

public class SavingAccount : Account {

public void Deposit() {…}}

public class CurrentAccount : Account {

public void Deposit() {…}}

  • if (…) Account obj = new SavingAccount();

else Account obj = new CurrentAccount();

obj.GetName(); //which method to call?

obj.Deposit(); //which method to call?

slide101
obj.GetName();
    • Not a virtual function, the method to call is known at compilation time
    • Static binding (bind at compilation time)
    • Account.GetName() is called
    • e.g. JMP 00ABCD //jump to the method
  • obj.Deposit();
    • obj is a pointer to different concrete xxxAccount object
    • the method to call can only be known at run time (because of polymorphism)
    • Run-time binding
run time binding or late binding
Run-time binding (or late binding)
  • Binding
    • The translation of name into physical address
  • Run-time binding
    • The translation is done at run-time
    • also known as
      • late binding
      • dynamic binding
  • Polymorphism depends on run-time binding
how run time binding polymorphism is implemented
How run-time binding (polymorphism) is implemented
  • Each class has a vtable (virtual table)
    • vtable contains addresses of thevirtualfunction
  • Every object has a vtable pointer (vptr) to the vtable

The Account vtable

an Account object

obj

vptr

attributes

Account.Deposit()

The SavingAccont vtable

a SavingAccount object

vptr

attributes

SavingAccount.Deposit()

obj

dynamic binding under the hood
Dynamic binding – under the hood
  • Compileobj.Deposit() to (*(obj->vptr[0]))(obj);
  • objis a pointer to the object
  • obj->vptris a pointer to vtable
  • obj->vptr[0]is the 1st slot in thevtable
    • becauseDeposit() is the first virtual method
  • *(obj->vptr[0])is the address ofDeposit()
  • (*(obj->vptr[0]))(obj)passesobjas ‘this’ pointer
  • If obj is an Account, then Account.Deposit() is called
  • If obj is a SavingAccount, then SavingAccount.Deposit() is called
more example
More example

A’s obj

A’s vtable

class A {

public void F0();

public virtual void F1();

public virtual void F2();

private int a;

}

class B : A {

public override void F1();

public virtual void F3();

protected int b;

}

vptr

int a

A.F1()

A.F2()

B’s obj

B’s vtable

vptr

int a

int b

B.F1()

A.F2()

B.F3()

F0 is a non-virtual method

F1() is overridden by B,

F2() has not been overridden,

F3() is new method in B,

why b can be treated as a
Why B can be treated as A
  • The top part of B is same as A, so it can be treated as A (upcasting, and hence polymorphism)

This part of B

is same as A

B’s vtable

B’s obj

&B.F1()

&A.F2()

&B.F3()

obj

vptr

int a

int b

why b still contains int a
Why B still contains int a?
  • ‘a’ is marked as private, cannot be accessed (or used) by B
  • But B can still use A.F2()
  • B may use the parent’s method A.F1(), which can be invoked by calling base.F1()
    • Both A.F1()and A.F2()can see and use ‘a’, therefore the object of B must provide the memory for it
one class many objects one vtable
One class, many objects, one vtable
  • A obj1 = new A();
  • A obj2 = new B();
  • B obj3 = new B();

A’s vtable

A’s object

obj1

vtpr

A.F1()

A.F2()

B’s object

B’s vtable

obj2

vtpr

B.F1()

A.F2()

B.F3()

B’s object

obj3

vtpr

multiple inheritance
Multiple inheritance
  • Objects can belong to more than one type
    • James is-a Student and a Photographer
  • Useful to have multiple inheritance

class StudentPhotographer : Student, Photographer

  • But it has problem with implementation ambiguity
    • The diamond problem
the diamond problem due to the shape of the diagram
The diamond problem (due to the shape of the diagram)
  • Person s = new StudentPhotographer();

s.Hello(); //Hello() has 2 implementations

//which Hello() to call?

Person

Hello();

Student

Hello(“Student”)

Photographer

Hello(“Photographer”)

StudentPhotographer

implementation and interface inheritance
Implementation and interface inheritance
  • The diamond problem
    • Multiple implementationinheritance
    • Which implementation to use? Ambiguity
  • Solution
    • Single implementation inheritance, but supports multiple interface
    • interface has no implementation, only abstract method
solution to the diamond problem
Solution to the diamond problem
  • StudentPhotographer inherits interface IPhotographer
    • StudentPhotographer must implement the abstract method Hello()
    • Only one implementation, no ambiguity

Person

Hello();

interface IPhotographer

abstract Hello()

Student

Hello(“Student”)

StudentPhotographer

slide113
Interface IPhotographer

{ void Hello(); } //visibility of hello() decided

//by the concrete subclass

  • class StudentPhotographer : Student, IPhotographer {

public override void Hello() {

Console.WriteLine(“StudentPhotographer”);

//or base.Hello(); reuse Student.Hello();

}

}

interface can be inherited
Interface can be inherited
  • interface IA

{ void Hello(); }

interface IB : IA

{ void MoreHello(); }

  • Multiple interfaces inheritance is OK

interface IC : IA, IB

{void YetMoreHello();}

  • Don’t have the diamond problem since we don’t have the problem of multiple implementations
notation used by microsoft
Notation used by Microsoft

denotes interface

Object

Student

IPhotographer

StudentPhotographer

IAstronomer

StudentAstronomer

Class inheritance

Interface inheritance

rtti run time type identification
RTTI – run time type identification
  • Let’s say we have an array of Student, StudentPhotographer, and StudentAstronomer
  • How to find student that can take IPhotographer.Photo()?
  • Student[] sa = {new Student{},

new StudentPhotographer(),

new StudentAstronomer()};

foreach (Student s in sa) s.Photo();

//Error: class Student does not support Photo()

rtti run time type identification1
RTTI – run time type identification
  • To select a specific type of object at run time
    • as keyword
    • foreach (Student s in sa) {

IPhotographer p = s as IPhotographer;

if (p!=null) p.Photo(); //OK

}

    • if s is-a IPhotographer, then p is a ref to the object; otherwise p=null
c data type
C# data type
  • In C#, everything are objects, and all objects are derived from System.Object

System.Object

class

String

Array

. . .

ValueType

Reference type

Void

struct

Double

Char

Int32

. . .

all objects are derived from system object
All objects are derived from System.Object
  • Methods in System.Object are inherited by all objects
  • Equals() – compare object reference only, not the state of the object
  • GetHashCode() – default returns a hash code (integer) of the reference to the object
  • GetType() – return a type object
  • ToString() – e.g. ClassStudent.Student
  • Finalize() – use to remove object from heap
  • MemberwiseClone() – return a shallow copy of object
syntax of inheritance1
Syntax of inheritance
  • The following constructs are the same

// explicitly derived from System.Object

class Student : System.Object {…}

//same, object is an alias of System.Object

class Student : object {…}

//implicitly derived from System.Object

class Student {…}

reference based semantics
Reference-based semantics
  • Methods in System.Object are based on reference semantic
  • e.g.Equals() compares the references of two objects
  • System.Object.Equals(object obj)

Student s1 = new Student(7,”James Bond”);

Student s2 = new Student(7,”James Bond”);

bool flag = s1.Equals(s2);

  • Question
    • Is flagtrue or false?
    • What sort of parameters are we comparing to?
slide122
Answer: flag=False
  • Reference semantic,compare references of s1 and s2
    • References of s1(FF0000) and s2(FF1000) are different

FF0000

s1

FF0000

James Bond

s2

FF1000

FF1000

James Bond

problems with reference type semantic
Problems with reference type semantic
  • Some types, such as integer and string, are based on value type semantic
    • i.e. the values are compared, not the addresses
  • Reference-type objects are expensive to maintain
    • Reference-type objects must be stored in the heap, cannot be removed cheaply (garbage collector is slow)
  • Reference-type objects takes up more memory
    • An integer takes up 4 bytes
    • An object takes up at least 12 bytes
      • 4 bytes for the object pointer, 4 bytes for the value; 4 bytes for the vtable pointer
a compromise
A compromise
  • Value-type objects (e.g. char, integer, bool, struct), override the reference-type semantic to value-type semantic
  • Value types and reference types
    • Value-based (int, double, bool, enum, struct)
      • Allocate in stack
      • Size of the variable is known at compilation time
    • Reference-based (objects, array)
      • Allocate in heap
      • Size is not known at compilation time (size of array can be changed dynamically)
system data type
System data type
  • char, int, and double are alias (shorthand) for:
    • char ->System.Char
    • int ->System.Int32
    • double ->System.Double
  • ValueType class is a subclass of System.Object that overrides and changes the methods from reference-based to value-based
conversion between reference type and value type
Conversion between reference type and value type
  • Boxing - value type to reference type
    • Wrap the value type object by an object wrapper
    • Put the object in heap
    • Value to reference conversion is called boxing
      • Like putting the value inside a box
  • Unboxing - reference type to value type
  • int i=3;
  • Object o = i; //boxing - convert to reference type
  • i = (int) o; //unboxing - convert back to value type
value based semantics
Value-based semantics
  • What if we want to compare the Student objects in terms of their ID?
    • The comparison is value-based rather than reference-based
  • Need to override the default method Equals()

class Student {

public override bool Equals(object obj) {

if (this.ID == obj.ID)

return true;

else

return false;

}

}

ID is a property in this example

gethashcode
GetHashCode()
  • The default is to hash the object’s reference

Student s1 = new Student(7,”James Bond”);

Student s2 = new Student(7,”James Bond”);

bool flag =

(s1.GetHashCode()==s2.GetHashCode());

  • Question
    • Is flagtrue or false?
  • Answer
    • false, in our example, s1=FF0000, s2=FF1000
gethashcode1
GetHashCode()
  • To hash the object by value, override GetHashCode()

class Student {

public override int GetHashCode() {

return ID.GetHashCode();

}

Invoke the built-in hashcode

method in type int,which

is value-based

ID is of type int

Value-base semantic

struct
struct
  • struct is a value type (size known at compilation time)

Main() {

Complex f = new Complex();

f.real = 1.0

f.imag = 2.0

}

struct Complex {

public double real; //default is private

public double imag;

}

difference between struct and class
Difference between struct and class
  • Same syntax
  • struct is value-type, memory allocated in the stack at compilation time, cannot be changed at run-time!
  • class is reference-type, only the reference pointer to the object is allocated in the stack
  • If you have permanent data that do not want to change, use struct
  • class is more flexible and is important in OO because the reference can point to different object at run-time (polymorphism)
struct vs class value vs reference type
struct Complex {

public double real;

public double imag;

}

Complex f1=new Complex();

Complex f2=new Complex();

f1.real=10;

f1.imag=20;

f2=f1; //copy value

f1.real = 99;

//f2.real=10, not changed

class Complex {

public double real;

public double imag;

}

Complex g1=new Complex();

Complex g2=new Complex();

g1.real=10;

g1.imag=20;

g2=g1; //copy ref!!

g1.real = 99;

//g2.real=99, changed!!

struct vs class (value vs reference type)
struct vs class value vs reference type1
struct

f1=f2, copy the value

f1.real=99,f2 is not changes

class

g2=g1, copy the reference

g1.real=99,g2 is changed

struct vs class (value vs reference type)

g1

g2

f1.real

f1.imag

f2.real

f2.imag

FF0000

FF0000

stack

stack

real

imag

heap

shallow copy and deep copy
Shallow copy

g2=g1, only copy the reference

the default

Deep copy

make a new copy of the object

You have to implement the ICloneable interface

Shallow copy and deep copy

g1

g2

g1

g2

FF0000

FF0000

real

imag

FF0000

FF1000

real

imag

real

imag

shallow copy
Shallow copy
  • Student s1 = new Student(7,”James”);
  • Student s2 = s1; //shallow copy
  • Only the address of s1 is copied to s2
  • For deep copy, use Clone()
deep copy by implementing the icloneable interface
Deep copy by implementing the ICloneable interface
  • Student s1 = new Student(7,”James”);

Student s2 = (Student) s1.Clone(); //deep copy

  • public interface ICloneable {

object Clone();

}

public class Student : ICloneable {

int studentID;

string name;

public object Clone() { //make a separate copy

return new Student(studentID, name);

}

}

Why casting?

Call constructor to build a new object

array in c
Array in C#
  • int[] a = {1, 5, 7, 3, 20};
  • System.Array has a number of built-in functions
  • Length – a property that shows the length of array
    • for (int i=0; i<a.Length; i++) {}
  • Sort
    • Array.Sort(a); //sort by a static function

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

Console.WriteLine(“element = {0}”,a[i]);

    • element = 1;

element = 3;

. . .

icomparable interface
IComparable interface
  • OK for Sort()to sort known type, e.g. int
  • But for user-defined type, we have a problem
  • Student[] sa = {new Student(7,”James”),

new Student(8,”GoldFinger”),

new Student(2,”Pokemon”);

Array.Sort(sa);

  • System.ArgumentException: at least one object must implement IComparable
  • The problem
    • Sort() does not know who to compare Student !
how sorting is done
How sorting is done
  • Sort() uses IComparable.CompareTo(object o) to compare objects and to do the sorting

Array

Sort()

IComparable

CompareTo()

objects container

icomparable interface1
IComparable interface
  • Array has an internal container to store the objects
  • Array provides methods like Sort() to process objects in the container
  • Sort() needs to compare the stored objects in some order in order to do the sorting
  • The comparison is done by CompareTo()
  • To support sorting, you must implement CompareTo() defined in IComparable interface
icomparable interface2
IComparable interface
  • Interface IComparable {

int CompareTo(object o);

}

  • CompareTo return value
    • Less than 0: this instance is less than object
    • 0: this instance is equal to object
    • Greaten than 0: this instance is greater than object

The type of the object is not known,

so it is upcasted to object

solution student implements the icomparable interface
Solution : Student implements the IComparable interface
  • public Student : IComparable {

int IComparable.CompareTo(object o) {

Student temp = (Student) o; //casting

//object can’t use Student’s methods

//explicit downcasting !!

if (this.studentID < temp.StudentID)

return -1;

if (this.studentID > temp.StudentID)

return 1;

else return 0;

}

. . .

}

operator overloading
Operator overloading
  • How to use operators like < and > to compare objects ?
  • Let’s s1 and s2 be the references to two Student objects
    • if (s1>s2) {. . .} //how to compare?
  • Treat operator> like a function call
    • this is known as operator overloading

public static bool operator> (Student s1,Student s2)

{

return ( s1.CompareTo(s2) > 0 );

}

operator overloading1
Operator overloading
  • Most of the c# operators can be overloaded
  • Operator overloading treats operator like static methods
  • Except
    • operator= (assignment operator) cannot be overloaded
      • to keep the semantic meaning of operator= simple
    • In c#, operator= always does a shallow copy of reference
    • For deep copy, use ICloneable interface
system collections smart container of objects
System.Collections – smart container of objects
  • Limitation of System.Array
    • The array size is fixed
  • System.Collections
    • Smart container, automaticresize, better than Array
  • Different type of smart container to choose from
    • ArrayList (most useful)
    • SortedList
    • Queue (FIFO)
    • Stack (LIFO)
    • Hashtable (objects identified by hashcode)
arraylist
ArrayList

using System.Collections;

ArrayList studentList = new ArrayList();

//add new entry, no need to define size

studentList.Add(new Student(7,”james”));

//add several entries

studentList.AddRange(new Student[]{ new Student(8,”gold”),

new Student(9,”Kit”)};

//insert to the 3rd position in the list

studentList.Insert(2, new Student(5,”Poke”));

foreach (Student s in studentList)

ConsoleWrite(“name {0}”, s.GetName());

how automatic resize is achieved
How automatic resize is achieved

class ArrayList : IList, ICollection, . . . {

private object[] list; //an array of objects

private int maxsize=10; //initial size of array

private int index=0; //next available slot

public Add(object o) {

if (index<maxsize) list[index++]=o;

else { //if array is full, increase size

maxsize = maxsisze + 10;

object[] newlist = new object[maxsize];

//. . . copy objects from list to the newlist

}

}

}

problem with container
Problem with container
  • Objects in the container must be upcasted to object
  • Why?
    • Because the container designer does not know the type of objects that will be stored
  • Problem
    • Since ALL type of objects will be upcasted to object, the container will accept ALL type of objects without flagging error, it is not type-safe
  • Solution
    • Build a type-safe container
type safe container
Type-safe container
  • Add a wrapper to ArrayList

public class StudentList : IEnumerable

{

private ArrayList list;

public StudentList() {list=new ArrayList();}

public void Add(Student s) {list.Add(s);}

. . .

}

The wrapper method, objects added to

the list must be of type Student

comparison
StudentList

StudentList slist =

new StudentList();

list.Add(new Student());

//OK

slist.Add((int)10);

//error detected by

compiler

ArrayList

ArrayList list =

new ArrayList();

List.Add(new Student());

//OK

list.Add((int)10);

//error not detected

by compiler

Comparison
ienumerable
IEnumerable
  • foreach does not know how to access StudentList since it is a user-defined container
  • Solution
    • Implement the IEnumerable interface
    • public class StudentList : IEnumerable
  • IEnumerable is a example of the Iterator pattern
  • Iterator
    • Iterator is an abstraction of sequentialcontainers
    • Iterator separates algorithms from data structures
iterator is an abstraction of sequential data structure
Iterator is an abstraction of sequential data structure
  • What is the commonality between array and link list?
    • Both are sequential data structure which has a beginning and an end

Linear array

Element 0 Element 1 . . . Element N

Link list

Element 0

Element 1

Element N

. . .

ienumerator interface
IEnumerator interface
  • Reset( )- make 1st element as current object
  • MoveNext()– next object as current object
  • Current – Property that return the current object

IEnumerator

void Reset();

Bool MoveNext();

object Current {get;…}

Linear array

Link list

design of foreach
Design of foreach
  • A container must support IEnumerable interface
  • foreach uses GetEnumerator()method in IEnumerable to get an object that implements the IEnumerator interface
  • Then use methods in IEnumerator to access elements in the sequential data structure
  • foreach (int i in array)
  • IEnumerator e = array.GetEnumerator();

while (e.MoveNext() {

i=(int)e.Current);

//. . .

}

custom implement of foreach for container studentlist
Custom implement of foreach for container StudentList
  • public class StudentList : IEnumerable {

private ArrayList list;

. . .

}

StudentList slist = new StudentList();

  • public interface IEnumerable {

IEnumerator GetEnumerator();

}

public IEnumerator GetEnumerator() {

//return the object that implements IEnumerator

return list.GetEnumerator();

}

Return an IEnumerator

ArrayList has already implemented

the IEnumerator interface

slide156

IEnumerator

void Reset();

Bool MoveNext();

object Current {get;…}

Linear array

Link list

StudentList

foreach

IEnumerable

IEnumerator GetEnumerator();

indexer for the type safe container
Indexer [] for the type-safe container
  • How to support indexed operation slist[0],slist[1],…
  • By implementing the this[] function
  • Similar to operator overloading, just different syntax
slide158
this[]

public class StudentList : IEnumerable {

private ArrayList list;

public Student this[int pos] {

get { //property

if (pos<0) throw new

IndexOutofRangeException(“out of range”);

else

return (Student)list[pos]; //casting

}

set {

list.Insert(pos, value);

}

}

generic programming
Generic programming
  • A better way to build a type-safe container
  • A major feature in C# 2.0
  • What is Generic programming?
    • Parameter substitution, a smart editor that does a find and replace
    • Source level polymorphism
a second look at arraylist
A second look at ArrayList
  • class ArrayList : IList, ICollection, … {

private object[] list; //an array of objects

. . . }

  • Bad because
    • Not a type-safe container, will accept any type of object without checking
    • If the elements are ValueType (e.g. integer), boxing operation is automatically performs to convert it to an object
      • Expensive both in memory used and in speed

The problem

a second look at arraylist1
A second look at ArrayList
  • Parameter substitution
  • class ArrayList<Type> : IList,ICollection,… {

private <Type>[] list;

. . .

}

  • ArrayList<Student>list =

new ArrayList<Student>();

  • Parameter Type is replaced by Student before compile
    • class ArrayList<Type> serves as a template
slide162
Generating a new class ArrayList container for a specific type (student)
    • class ArrayList : IList, ICollection,… {

private Student[] list;

. . .

}

  • No need to write your own code! Fast and without error.
  • Generic programming can generate not only classes, but also algorithms
generic algorithms
Generic algorithms
  • Problem with void swap(int ref x, int ref y){…}
    • Work only for integer
  • The template
    • void swap(<TypeA> ref x, <TypeA> ref y) {

<TypeA> temp=x; x=y; y=temp; }

  • Student x; Student y; swap(ref x, ref y);
  • compiler generates a type specific method

void swap(Student ref x, Student ref y) {

Student temp=x; x=y; y=temp; }

two keys features in generic programming
Two keys features in generic programming
  • Template
    • Solve the problem with type
    • Write one template, work for all type of classes and algorithms
    • Source level polymorphism
  • Iterator
    • Iterator is an abstraction of sequentialcontainers
    • Iterator separates algorithms from data structures
separation of algorithms and data structures
Separation of algorithms and data structures
  • Algorithm – write one template, works for all types
  • Structure – write one template, works for all types
  • Iterator makes all sequential containers look the same
  • No more coding for data structure and common algorithms

Generic algorithms

Iterator

Sequential data structures

how to handle runtime exceptions
How to handle runtime exceptions
  • Exceptions are not bugs (bug is programming error and must be fixed)
    • e.g. file not found, fail to connect to a database, etc
  • Traditional way of handling exceptions
    • Return a number as return value
      • e.g. ErrMsg Foo();
    • A number carries little information
      • Need a codebook to know its meaning
      • No corpse, don’t know what happened
exception handling
Exception handling
  • The modern way of handling exception
    • Return an exception object that can carry more information
    • Out-of-band signal, does not mix up with return value
    • A cleaner way, used by C++, Java, and C#
to throw an exception object
To throw an exception object

class foo {

public void Bar() {

// open a file …

if (file_not_open) throw

new Exception(“file not opened”);

}

}

to catch an exception object try and catch block
To catch an exception object – try and catch block

Main() {

Foo f = new Foo();

try {

f.Bar(); //call a method

}

//exec only if an Exception object is returned

catch (Exception e) {

Console.WriteLine(“Message: {0}”, e.Message);

Console.WriteLine(“Source: {0}”, e.Source);

Console.WriteLine(“Method: {0}”, e.TargetSite);

}

}

some of system exception s methods
Some of System.Exception’s methods

Exception(); //constructor

Exception(string message); //constructor

string Message { virtual get; }

//return message

string Source { virtual get; virtual set; }

//name of the assembly that threw the exception

string StackTrace { virtual get; }

//the sequence of calls that caused the exception

MethodBase TargetSite { get; }

//about the method that threw the exception

to have your own exception object
To have your own exception object
  • Need to write three constructors

public FileNotOpenException : System.Exception {

public FileNotOpenException(){. . .}

public FileNotOpenException(string message)

: base(message){. . .}

public FileNotOpenException(string message,

Exception innerEx): base(message,innerEx){. . .}

}

  • These constructors invoke the base constructor first, then call their own code
catching different levels of exception objects
Catching different levels of exception objects

try {

f.Bar();

}

catch (FileNotOpenException e)

{. . .} //catch specific exception first

catch (Exception e)

{. . .} //then catch general exception

finally //optional

{. . .} //in case nothing can be caught

rethrow
Rethrow
  • Catch an exception, do something, throw it up the chain

try {

f.Bar();

}

catch (FileNotOpenException e) {

//do something to e here

throw e; //rethrow

}

  • Exception must be handled
    • If not caught, the exception object will be passed all the way up to Main(); a dialog window will pop up, which is annoying to users
what do we mean by inheritance
What do we mean by inheritance?
  • Focused on the behavior of the class
  • Is Square a kind of Rectangle?
  • Behavior of Rectangle
    • Width and Height
    • Area = Width * Height
  • Behavior of Square
    • Width = Height

Rectangle

Square

slide175
If Square is-a kind of Rectangle, then

Rectangle rect = new Square();

rect.Width = 10;

rect.Height = 20;

//what is rect.Area?

Console.WriteLine(“Area={0}”,rect.Area);

  • Square will probably make Width = Height, so rect.Area=400, which is not what we expect
  • From OO point of view, a Square is NOT a kind of Rectangle
liskov substitution principle
Liskov Substitution Principle
  • Objects of derived classes should be able to substitute objects of base classes without problem
  • What is wrong with Square-isa-Rectangle?
    • Is-a relationship means that the behavior of the subclass must conform to the base class
    • Square has different behavior than Rectangle , hence Square is-not-a Rectangle
  • It is behavior inheritance that we want
design by contract
Design by contract
  • What is a contract
    • Classes are written by different parties
    • If thing goes wrong, need to know who has the responsibility in fixing the problem
    • Contract is the specifications on the obligations between the calling class (client) and the called class (server)
  • Ref:
    • Design by Contract – a conversation with Bertrand Meyer (http://www.artima.com/intv/contracts.html)
contract specifications
Contract specifications
  • Pre-condition
    • The obligation that the client must fulfill in making a call to the server
    • Obligation is enforced by making assertion
    • Assertion (assert()) is a boolean statement that checks the validity of the parameters, an assertion can never be false
  • Post-condition
    • Specify the obligation that the server must fulfill after servicing the call
  • Invariant
    • An assertion about the class
    • e.g. balance = income – expense;
contract and subclassing
Contract and subclassing
  • Liskov Substitution Principle
    • Objects of derived classes should be able to substitute objects of base classes without problem
  • A subclass can weaken (relax) the pre-conditions but cannot strengthen them
  • A subclass can strengthen (tighten) the post-conditions and invariants, but cannot weaken them
  • The pre-condition of Square is tighter than Rectangle(width==height) => problem
  • Thus Square should not be a subclass of Rectangle
contract and exception
Contract and exception
  • Exception is NOT a bug
    • Bug (programming error) should be corrected
  • A definition of exception in terms of contract
    • An exception occurs when an operation is invoked with its pre-condition satisfied yet cannot return with its post-condition satisfied

(Fowler, UML Distilled (3rd))