6[1].interfaces and collections

86
Interfaces and Collections Chapter - 6

Upload: naveen-kumar

Post on 23-Oct-2015

19 views

Category:

Documents


1 download

DESCRIPTION

CS Notes

TRANSCRIPT

Interfaces and Collections

Chapter - 6

C#C#C#C#

C# C# C#C#

2

Objectives Interface – basic concepts How to implement Interfaces in C#? Difference between Interfaces and

Abstract base Classes Interface References: 'is', 'as', etc. Interfaces as Parameters Interfaces and Polymorphism Building Customized Types

IConvertible, IEnumerator, ICloneable, and IComparable, Interfaces

System.Collections Interface ArrayList, Hashtable, Queue, SortedList, and Stack

C#C#C#C#

C# C# C#C#

3

Why Interfaces?

They're great for putting together plug-n-play like architectures where components can be interchanged at will (example follows…). 

Since all interchangeable components implement the same interface, they can be used without any extra programming. 

The interface forces each component to expose specific public members that will be used in a certain way.

C#C#C#C#

C# C# C#C#

4

USB

Real World Example

Interface1Interface2

Interface3

C#C#C#C#

C# C# C#C#

5

Interface – Basic Concepts Definition: An interface is nothing more than a

named collection of semantically related abstract members

Interface is to achieve polymorphism in another way Interfaces can have static members, nested types,

and abstract, virtual members, properties, and events COM programmers lived only with interfaces, as the

client can communicate only through interface pointers with COM classes (not through object references)

Interfaces do not specify a base class (not even System.Object), and contain members do not take access modifiers.

Interfaces do not implement any methods

C#C#C#C#

C# C# C#C#

6

Contd..Syntax:

interface interfaceName{ member declarations; }

Here, interface is the keyword Eg: interface show

{ void display(); } Interface can also declare properties & eventsEg: interface Ex1

{ int Aproperty{ get; } // behavior as a read-only

propertyevent SomEevent changed;void Display();

} Accessibility of an interface can be controlled by

modifiers public, private, internal & protected

C#C#C#C#

C# C# C#C#

7

Extending an Interface Interface extension – an interface can be subinterfaced from

other interfaces. New subinterface will inherit all the members of the

superinterfaceEg1: interface Addition

{ int Add(int x, int y); }interface Compute:Addition{ int sub(int x, int y); }

Eg2: interface I1{ …. }interface I2{ …. }interface I3: I1,I2 // multiple inheritance{ …. }

Subinterfaces cannot define the method declared in the superinterfaces.

An interface cannot extend the classes.

C#C#C#C#

C# C# C#C#

8

Implementing an Interface

A class that implements an interface can explicitly implement a member of that interface. i.e., interfaces are used as ‘supeclasses’ whose properties are inherited by classes.

Interfaces may be implemented by classes and structures

public interface ISomeInterface{

// Members….. }public class SomeClass : ISomeInterface{

// implementation details of the interface }public class AnotherClass : BaseClass, ISomeInterface{

// derives from BaseClass and implents the interface}

C#C#C#C#

C# C# C#C#

9

Example// program to illustrate implentation of multiple interfaceUsing System;interface Addition{ int Add(); }Interface Multiplication{ int mul(); }

Public computation (int x, int y) // constructor{ this.x = x;

this.y = y;}Public int Add ( ){ return (x+y); }Public int Mul ( ){ return (x*y); }}

C#C#C#C#

C# C# C#C#

10

ExampleClass InterfaceTest{ public static void Main()

{ computation com = new computation (10,20);Addition add = (Addition) com; // castingCW(“Sum = “ + add.Add());Multiplication mul = (Multiplication) com; // castingCW(“Product = “ + mul.Mul());

}}

Note: Cannot instantiate an interface directly. i.e.,Addition add= new Addition(); //error

Always create an instance of the implementing class & then cast the object to the interface type.

C#C#C#C#

C# C# C#C#

11

Interfaces Abstract base Classes Abstract base classes permit more than the abstract

methods – private, public, protected member data and methods which could be accessed in derived classes

In Interfaces, you can't define other than abstract methods and implementations for theminterface IPoints

{int myint=0; // error, interfaces can’t define data

byte GetNumberOfPoints() { } // ERROR, only abstract members allowed

}

Interfaced programming provides another way of polymorphism

C#C#C#C#

C# C# C#C#

12

Contd.. An abstract base class can use an interface in the base class list.Eg: interface A

{ void Method(); }abstract class B:A{ …..

public abstract void method();}

Note: the class B does not implement the interface method, it simply redeclare as a public abstract method.

We can convert an interface into an abstract classinterface A{ void Print(); }abstract class B{ abstract public void Print(); }Note: a class can inherit from B instead of implementing the interface

A.

C#C#C#C#

C# C# C#C#

13

Shapes Hierarchy

Shapes ClassDraw( )

Hexagon Class

Circle ClassTriangle

Class

Draw() Draw() Draw()

Ipointy Ipointy

C#C#C#C#

C# C# C#C#

14

Invoking Interface Members at the Object Level The most straightforward way to interact with functionality supplied by a

given interface is to invoke the methods directly from the object level.Eg: public interface IPointy

{ byte Points { get; } } // Hexagon implements IPointypublic class Hexagon : Shape, IPointy{ …..

public byte Points{ get {return 6;} }

}Class Example{ static void Main (string [ ] args) { Hexagon hex = new Hexagon();

CW (“Points : {0}”, hex.Points); }}

In specific case it works fine.

C#C#C#C#

C# C# C#C#

15

Contd… Assume if an array contains 50 shapes – compatible types, only some of which

support IPointy. Obviously, if you attempt to invoke the Points property on a type that has not implementes IPointy, then you receive a compiler error

This problem can be solved by 3 ways1. Explicit Cast2. As Keyword3. Is Keyword

1. Use an explicit cast of specific interface to determine at runtime. For this use structured exception handling

Eg: static void Main(string [ ] args){ ……Circle C = new Circle (“ L”);Ipointy pt1;try{ pt1 = (iPointy) C;

CW (pt2.Points);} Catch (InvalidCastException e){ CW (“OOPS! Not a pointy..”); }}

C#C#C#C#

C# C# C#C#

16

Interface Reference through is & as Using "as" keyword, you can reference the interface members

Hexagon h2 = new Hexagon();IPoints ipts2;ipts2 = h2 as IPointy;If (ipts2 != null)

Console.WriteLine(ipts2.Points);Else

Console.WriteLine (“OOPS! Not Pointy…”); ipts2 may be set to null if a given interface is not supported by the

object You can also use "is" keyword

Hexagon h2 = new Hexagon();if (h2 is IPointy)

Console.WriteLine(ipts2.GetNumberOfPoints());else

ERROR h2 may be set to false if a given interface is not supported by the

object

C#C#C#C#

C# C# C#C#

17

Another example for ‘is ‘Shape[ ] s = {new Hexagon(), new Circle(),

new Triangle("Joe"), new Circle("JoJo")};for (int i = 0; i < s.Length; i++){

s[i].Draw();// Who's points?

if (s[i] is IPointy)Console.WriteLine("-> Points: {0}",

((IPoints)s[i]). Points);

elseConsole.WriteLine("-> {0}\'s not points!", s[i].PetName);

}

C#C#C#C#

C# C# C#C#

18

Interfaces as Parameters Methods can take interfaces as parameters, as well as method

return values Assume the following interface:

public interface IDraw3D{

void Draw3D();}

Now assume that the Circle subclass is revised to provide an additional implementation for IDraw3Dpublic class Circle : Shape, IDraw3D{

……….public void Draw3D(){ Console.WriteLine("Drawing a 3D Circle");

}

C#C#C#C#

C# C# C#C#

19

Interface as Parameter…Public class Hexagon: Shape, Ipointy, IDraw3D{ ….

public void Draw3D(){ CW (“Drawing Hexagon 3D”); }

}Public class ShapeApp{ public static void DrawShape(IDraw3D objdraw) // parameter passing

{Console.WriteLine("Drawing in 3D: compatible type");if (objdraw is IDraw3D)return (IDraw3D)objdraw; // returning valueelsereturn null;

}

C#C#C#C#

C# C# C#C#

20

Interface as Parameter…Public static void Main(){ Hexagon H=new Hexagon();

Circle C=new Circle();IDraw3D Hobj=Drawshape(H);if (Hobj!=null)

CW(“It is a 3D Hexagon”);else

CW(“Not 3D object”);IPointy Cobj=Drawshape(C);If (Cobj!=null)

CW(“It is a 3D Circle”);else

CW(“Not a 3D object”);}}

Output

Drawing IDraw 3D compatible type

It is an 3D Hexagon

Drawing IDraw 3D compatible type

Not a 3D object

C#C#C#C#

C# C# C#C#

21

Explicit interface Implementation C# does not support multiple inheritance – problem is

name collisioneg: interface I1 { void Display(); }

interface I2 { void Display(); }class c1: I1,I2{ public void Display { }}

Now, does c1.Display implement I1.Display or I2.Display? // compiler reports ambiguous

To solve this – use technique explicit interface implementation

It allows a method to specify explicitly the name of the interface it is implementing.

C#C#C#C#

C# C# C#C#

22

Example Explicit Interface Implementation

public interface IDimensions {

float Length();float Width();

}

class Box : IDimensions {

float lengthInches;float widthInches;

public Box(float length, float width) {

lengthInches = length;widthInches = width;

}

C#C#C#C#

C# C# C#C#

23

Example…

// Explicit interface member implementation:

float IDimensions.Length()

{

return lengthInches;

}

// Explicit interface member implementation:

float IDimensions.Width()

{

return widthInches;

}

C#C#C#C#

C# C# C#C#

24

public static void Main() {

// Declare a class instance "myBox":Box myBox = new Box(30.0f, 20.0f);// Declare an interface instance "myDimensions":IDimensions myDimensions = (IDimensions) myBox;// Print out the dimensions of the box:/* The following commented lines would produce compilation errors because they try to access an explicitly implemented interface member from a class instance: *///Console.WriteLine("Length: {0}", myBox.Length());//Console.WriteLine("Width: {0}", myBox.Width());/* Print out the dimensions of the box by calling the

methods from an instance of the interface: */Console.WriteLine("Length: {0}", myDimensions.Length());Console.WriteLine("Width: {0}", myDimensions.Width());

}}

Example…

C#C#C#C#

C# C# C#C#

25

Building Interface Hierarchies Possible to build inheritance relationships among interfaces Top most interface defines general behavior and most derived interface

defines more specific behaviorEg: public interface Ibase

{ void Draw(); }

public interface Iderv1: Ibase{ void Print(); }public interface Iderv2: Iderv1{ void Render(); }

// A class derives from nth-most interfacepublic class Super :Iderv2

{ void Draw(){ CW(“Basic drawing logic”); }void Print(){ CW(“Draw to printer”); }void render(){ CW(“Render to derive file”); }

}

C#C#C#C#

C# C# C#C#

26

Building Interface HierarchiesClass Samp{ static void Main(string[ ] srgs)

Super Si=new Super();Ibase b1=(Ibase)Si;b1.Draw();if (b1 is Iderv2){ Iderv2 d2 = (Iderv2) b1;

d2.Render();d2=Print();

}}}

C#C#C#C#

C# C# C#C#

27

Interfaces with multiple Base Interfaces Permissable to creat an interface that derives from multiple base interfacesEg: public interface IYCar

{ void Drive(); }public interface IXCar IXCarderv1: Ibase{ void Dive();}public interface Iderv2: IYCar, IYCar{ void Turbo(); }

public class Car:IZCar { void Drive()

{ CW(“Speeding up…”); }void Dive(){ CW(“Submerging…”); }void Turbo(){ CW(“Blast off); }

}….Static Void Main(string[ ] args){ ….

Car C1=new Car();C1.Drive();C1.Turbo();C1.Dive();

}

C#C#C#C#

C# C# C#C#

28

Implementing Interfaces using Visual Studio 2005

Assume, implement the ICar interface on a new class names MiniVan

The first letter is underlined [ smart tag ] Click on smart tag – provides selection to

implement the interface explicitly or implicitly Built automatically stub code wrapped in a

#region/#endregion

C#C#C#C#

C# C# C#C#

29

Undestanding the IConvertible Interface

Allows to dynamically convert b/w data types It is defined as follows:Public interface IConvertible{ TypeCode GetTpeCode();

bool ToBoolean (IFormatProvider Provider);byte ToByte (IFormatProvider Provider);char ToChar (IFormatProvider Provider);DateTime ToDateTime (IFormatProvider Provider);double ToDouble (IFormatProvider Provider);short ToShort (IFormatProvider Provider);int ToInt32 (IFormatProvider Provider);float ToSingle (IFormatProvider Provider);string ToStrring (IFormatProvider Provider);

Object ToType (Type ConversionType IFormatProvider Provider);}

C#C#C#C#

C# C# C#C#

30

Undestanding the IConvertible Interface . .

To access each member of IConvertible interface, explicitly request access to the interface

Eg: bool myBool=true

IConvertible Conv = (IConvertible) myBoll;

C#C#C#C#

C# C# C#C#

31

The IConvertible.ToXXXX() members IConvertible defines a number of methods of

the form ToXXXX(), it provides a way to convert from one type into another

System types throw an InvalidCaseException if the conversion is semantically error.

Eg: bool myBool = true;Iconvertible Conv =(IConvertible)

myBool;try{ Conv.ToSingle(…); }catch (InvalidCastException e){ CW (e); }

C#C#C#C#

C# C# C#C#

32

IFormatProvider

all ToXXXX() methods take a parameter of type IFormatProvider

Objects that implement this interface are able to format their contents based on culture-specific information (eg. Float fomatted in various currencies)

Definition:public interface IFormatProvider{ Object GetFormat(Type formatType); }

Custom type – IFormatProvider implementation necessary System type - call from System.Globalization.CultureInfo

IConvertible Conv = (IConvertible) theInt;byte theByte = Conv.ToByte(CultureInfo.CurrentCulture);CW(“Type code int converted to byte is :{0}” , theByte.GetTypeCode());CW(“Value of converted int :{0}”, theByte);

C#C#C#C#

C# C# C#C#

33

IConvertible.GetTypeCode()

Available to any class or structure implemeting IConvertible

Allows to programmatically discover a value that represents the typecode of the type, which is represented by the following enumeration:public enum TypeCode{ Boolean, Byte, Char, DateTime, DBNull,

Decimal, Double, Empty, Int16, Int32, Int64, object, SByte, Single, String, UInt16, UInt32, UInt64}

C#C#C#C#

C# C# C#C#

34

Building a custom Enumerator (IEnumerable & IEnumerator) IEnumerable & IEnumerator are defined by System.Collection namespaceEg: assume a class Cars that contains a set of individual Car types stored in

System.ArrayPublic class Cars{ Private Car[ ] CarArray;

public Cars(){ CarArray = new Car[4];

CarArray[0] = new Car(“Rashu”, 30);CarArray[1] = new Car(“Charan”, 55);CarArray[2] = new Car(“Zohra”, 20);CarArray[3] = new Car(“Hema”, 30);

}}Public class Program{ static void Main(string[] args)

{ Cars CarLot=new Cars();foreach(Car C in CarLot)

CW(“{0} is going {1} MPH”, C.PetName, P.CurrSp);}

}

C#C#C#C#

C# C# C#C#

35

Contd… When tried for execution – gives error “the

Cars class does not implement a method GetEnumerator()”

GetEnumerator defined by IEnumberable interface

IEnumerable informs- object’s subitems can be enumerated.

Formal definition of IEnumerable is:public interface IEnumerable{ IEnumerator GetEnumerator(); }

C#C#C#C#

C# C# C#C#

36

Contd… GetEnumerator() returns a referance to another

interface names System.Collections.IEnumerator. IEnumerator interface allow to traverse the internal

objects contained by the IEnumerable – compatible type.

public interface IEnumerator{ bool MoveNext(); // Advance the internal position of

the cursorobject Current{ get; } // Get the current item void Reset(); // Reset the cursor before the first

member} So update the program as follows.

C#C#C#C#

C# C# C#C#

37

Contd…using System.Collections;….public Class Cars:IEnumerable{ private car[ ] CarArray;

public Cars(){ CarArray = new Car[4];

CarArray[0] = new Car(“Rashu”, 30);CarArray[1] = new Car(“Charan”, 55);CarArray[2] = new Car(“Zohra”, 20);CarArray[3] = new Car(“Hema”, 30);

}Public IEnumerator GetEnumerator(){ //return the array object’s IEnumerator

return CarArray.GetEnumerator();}} Now safely use the type within the c# foreach construct.

C#C#C#C#

C# C# C#C#

38

Advantage : Reducing the Code Size Since the System.Array type already implements

IEnumerator, you need not add this interface to Cars classpublic class Cars : IEnumerable //, IEnumerator{

private car[ ] carArray; …….. public IEnumerator GetEnumerator(){ return carArray.GetEnumerator( ); }……..

} With this, there is no need to implement manually

MoveNext(), Reset(), etc.

C#C#C#C#

C# C# C#C#

39

Shapes Hierarchy

Shapes ClassDraw( )

Hexagon Class

Circle ClassTriangle

Class

Draw() Draw() Draw()

C#C#C#C#

C# C# C#C#

40

Example-1 : Shapes Hierarchy

public interface IPoints{

byte Points{get;}}public abstract class Shape{

protected string petName; // Constructors.

public Shape(){petName = "NoName";}public Shape(string s){ this.petName = s; }public abstract void Draw();

}

C#C#C#C#

C# C# C#C#

41

Circle SubClass

The Circle subclass does not implement the interface IPoints!public class Circle : Shape

{

public Circle() { }

// Call base class constructor.

public Circle(string name): base(name) { }

public override void Draw()

{

Console.WriteLine("Drawing " + PetName + " Circle");

}

}

C#C#C#C#

C# C# C#C#

42

Hexagon SubClasspublic class Hexagon : Shape, IPoints{

public Hexagon(){}public Hexagon(string name): base(name){}

public override void Draw(){ Console.WriteLine("Drawing " + PetName +

"Hexagon");}

// Implements IPointspublic byte Points{

get{ return 6; }}

}

C#C#C#C#

C# C# C#C#

43

Example-1…

public static int Main(string[] args)

{

Circle c = new Circle("Red");

c.Draw();

Hexagon h = new Hexagon("Blue");

h.Draw();

//IPoints MyShape = (IPoints) h;

//Console.WriteLine(MyShape.GetNumberOfPoints());

Console.WriteLine(h.GetNumberOfPoints());

return 0;

}ERROR

C#C#C#C#

C# C# C#C#

44

Example - 2

Interfaces can contain named properties Person Example:

public interface IAge

{

int Age {get; }

string Name {get;}

}

C#C#C#C#

C# C# C#C#

45

Example – 2…class Person : IAge{

private string firstName;private string lastname = "......";private int yearBorn;public int Age{

get { return DateTime.Now.Year - yearBorn; }set { yearBorn = value; }

}

public string Name

{

get { return firstName + " " + lastname; }

set { firstName = value; }

}

C#C#C#C#

C# C# C#C#

46

Example – 2…static void Main(string[] args){

Person p = new Person();p.Name = "Geetha";p.Age = 1986;Console.WriteLine("Name =

{0}",p.Name);Console.WriteLine("Age = {0}",p.Age);

IAge[ ] AgeArray = new IAge[2];// ………..

}}

C#C#C#C#

C# C# C#C#

47

Part - II IConvertible

Dynamic conversion of data types

IEnumerator and IEnumerable Standard interface implemented by classes that support

iteration over contained objects

ICloneable To provide a standard way to create copies of existing objects

IComparable and IComparer For oredering purpose (string and numeric)

IDictionary To map keys to values – “Associative arrays”

IList Access to individual items, removal, and insertion at any

point

C#C#C#C#

C# C# C#C#

48

IConvertible Interface Allows dynamic conversion of data types through

interface based programming technique What are the methods defined in IConvertible

Interface?public interface IConvertible

{bool ToBoolean(IFormatProvider provider);

char ToChar(IFormatProvider provider);

……

UInt64 ToUInt64(IFormatProvider provider);

}

C#C#C#C#

C# C# C#C#

49

Accessing Members To gain access to each member of IConvertible

interface, you must explicitly request access to the interface// uses explicit interface implementation

bool myBoll = true;

IConvertible i = (IConvertible) myBool; Now i is convertible to any valid type IConvertible.ToXXXX() Methods

These methods provide a way to convert from one type into another (is it always?!!!)

From char to DateTime possible? No If attempted, InvalidCastException will be raised

C#C#C#C#

C# C# C#C#

50

Type Conversions Integer

int theInt = 65;Console.WriteLine("Type code of int is: ",theInt.GetTypeCode());

Int to Char using Type Castingchar theChar = (char)theInt; Console.WriteLine("Type code int converted to char is: {0}",

theChar.GetTypeCode());Console.WriteLine("Value of converted char: {0}", theChar);

Int to Byte using IConvertibleIConvertible itfConvert = (IConvertible)theInt;byte theByte = itfConvert.ToByte(CultureInfo.CurrentCulture);Console.WriteLine("Type code int converted to byte is: {0}",

theByte.GetTypeCode());Console.WriteLine("Value of converted int: {0}", theByte);

using System.Globalization;

C#C#C#C#

C# C# C#C#

51

Type Conversion… Convert a System.String into a System.Boolean

using System.Convert

string theString = "true";

bool theBool = Convert.ToBoolean(theString);

Console.WriteLine("Type code string converted to bool is: {0}",

theBool.GetTypeCode());

Console.WriteLine("Value of converted string: {0}", theBool);

Add two integersint a = Convert.ToInt32(Console.ReadLine());

int b = Convert.ToInt32(Console.ReadLine());

Console.WriteLine("a + b = {0}", a+b);

C#C#C#C#

C# C# C#C#

52

Invalid Type Conversion// Exceptionbool myBool = true;IConvertible i = (IConvertible) myBool;try{

DateTime t = i.ToDateTime(CultureInfo.CurrentCulture);}catch (InvalidCastException e){

Console.WriteLine(e.Message);}

Objects that implement this interface are able to format their contents based on culture specific information

Invalid type conversion

C#C#C#C#

C# C# C#C#

53

Building a Custom Enumerator IEnumerable: Exposes the enumerator, which

supports a simple iteration over a collection GetEnumerator(): Public method that returns an

enumerator that can iterate through a collection Defined in System.Collections namespace

IEnumerator: Supports a simple iteration over a collection MoveNext(): Public method which advances the

enumerator to the next element of the collection

There are several classes which implement IEnumerable and IEnumerator interfaces. For example, Array, ArrayList, Stack, Queue, etc. are the classes that implement IEnumerable interface

C#C#C#C#

C# C# C#C#

54

Example – Car Class Cars class is a collection of Car objects using Array type

public class Cars {

// This class maintains an array of cars.private Car[ ] carArray;// Current position in array.// int pos = -1;public Cars(){

carArray = new Car[4];carArray[0] = new Car("FeeFee", 200, 0);carArray[1] = new Car("Clunker", 90, 0);carArray[2] = new Car("Zippy", 30, 0);carArray[3] = new Car("Fred", 30, 0);

}}

C#C#C#C#

C# C# C#C#

55

Iterating thro' the Collection Can we write the following code to iterate through the collection?

public class CarDriver{

public static void Main(){

Cars carLot = new Cars();Console.WriteLine("Here are the cars in your lot");foreach (Car c in carLot){

Console.WriteLine("-> Name: {0}", c.PetName);Console.WriteLine("-> Max speed: {0}",

c.MaxSpeed);Console.WriteLine();

}}

}

This code issues an error for not implementing the GetEnumerator() method

C#C#C#C#

C# C# C#C#

56

Implementing GetEnumerator() To get around the problem of compilation error, we must use

public class Cars : IEnumerable{

…….. // GetEnumerator() returns IEnumerator public IEnumerator GetEnumerator(){ // ??????? }……..

}

IEnumerable.GetEnumerator() returns an object implementing IEnumeratorpublic interface IEnumerator{

bool MoveNext();object Current { get; }void Reset();

}

C#C#C#C#

C# C# C#C#

57

Updating Cars Typepublic class Cars : IEnumerable, IEnumerator

{

……..

public IEnumerator GetEnumerator()

{

return (IEnumerator) this;

}

……..

}

C#C#C#C#

C# C# C#C#

58

Implementation of MoveNext()….

public bool MoveNext(){

if(pos < carArray.Length){

pos++;return true;

}else

return false;}

public bool MoveNext(){

if(pos < carArray.Length){

pos++;return true;

}else

return false;}

public void Reset()

{

pos = 0;

}

public object Current

{

get

{

return carArray[pos];

}

}

public void Reset()

{

pos = 0;

}

public object Current

{

get

{

return carArray[pos];

}

}

C#C#C#C#

C# C# C#C#

59

Advantages

User types can be iterated through 'foreach' loop

When the IEnumerator members are explicitly implemented, we provide an alternate method of accessing the objects in the container

C#C#C#C#

C# C# C#C#

60

Reducing the Code Size Since the System.Array type already implements

IEnumerator, you need not add this interface to Cars classpublic class Cars : IEnumerable //, IEnumerator{

private car[ ] carArray; …….. public IEnumerator GetEnumerator(){ return carArray.GetEnumerator( ); }……..

} With this, there is no need to implement manually

MoveNext(), Reset(), etc. (refer ObjEnum folder)

C#C#C#C#

C# C# C#C#

61

Building Cloneable Objects Recall System.Object has a member

MemberwiseClone() which does shallow copy

Object users can call this method with an instance for cloning process

Implementing ICloneable interface using a Point Class

Let us make things clear……

C#C#C#C#

C# C# C#C#

62

Examplepublic class Point { public int x, y; public Point(){}

public Point(int x, int y) { this.x = x; this.y = y; } public override string ToString(){ return "X: " + x + " Y: " + y; }

} The following piece of code makes two references

pointing to the same copy of the objects in heapPoint p1 = new Point(50, 50);Point p2 = p1;p2.x = 0;

Notice that by modifying p2, the object p1 also gets modified.

C#C#C#C#

C# C# C#C#

63

ICloneable Interface To avoid the shallow copy problem we must

implement the ICloneable interfacepublic interface ICloneable{

object Clone();}

This means the Clone() method need to be redefined to suit the customer type. This ensures deep copy semanticspublic class Point : ICloneable{

…..public object Clone(){ return new Point(this.x, this.y); }….

}

C#C#C#C#

C# C# C#C#

64

Calling Clone() MethodPoint p1 = new Point(50, 50);// p2 will point to the copy of p1Point p2 = (Point)p1.Clone();p2.x = 0; // will not affect p1Console.WriteLine(p1);Console.WriteLine(p2);

The above WriteLine commands will print two different objects

If a type does not contain references to other internal reference types, then we can writepublic object Clone()

{ return this.MemberwiseClone(); }

What happens if the Point type contains references to other internal reference types? [it becomes a shallow copy]

If we wish to support a true deep copy, we need to create a new instance of any reference type variables during the cloning process.

C#C#C#C#

C# C# C#C#

65

Building Comparable Objects IComparable interface defines a generalized comparison

method that a value type or class implements to create a type-specific comparison method

CompareTo(object o) - Compares the current instance with another object of the same typepublic interface IComparable{

int CompareTo(object o);}

Recall, the System.Array class defines a method Sort() which sorts int, float, char, etc. However, if the array contains a set of Cars, it fails.Array.Sort(intArr); // OKArray.Sort(myCars); // ArgumentException will be thrown

So the advantage of IComparable is to provide a way to sort your own types

C#C#C#C#

C# C# C#C#

66

Example – Student Classpublic class Student : IComparable{

private int USN;public Student() {USN = 0; }public Student(int USN) { this.USN = USN; }public int RegNo{

get{ return USN; }

}

int IComparable.CompareTo(object o){

Student temp = (Student) o;if(this.USN > temp.USN) return 1;if(this.USN < temp.USN) return -1;else return 0;

}}

CompareTo() return Value:

< 0 : comes before the specified object

0 : equal to specified object

> 0 : comes after the specified object

C#C#C#C#

C# C# C#C#

67

Sorting the Objectsstatic void Main(string[] args){

Student[] cseStd = new Student[3];cseStd[0] = new Student(111);cseStd[1] = new Student(100);cseStd[2] = new Student(45);

try{

Array.Sort(cseStd);}catch(Exception e){

Console.WriteLine(e.StackTrace);}Console.WriteLine("Array after sorting");foreach(Student s in cseStd)

Console.WriteLine(s.RegNo); }

C#C#C#C#

C# C# C#C#

68

Sorting Order (IComparer) Suppose if you wish to sort the student objects based

on USN and also Name – how do we solve this problem?

This could be solved by using another interface called IComparerpublic interface IComparer{

int Compare(object o1, object o2)}

Recall, the IComparable interface was implemented using the type name (Student). But, IComparer is implemented using some helper classes, one for each sort order (USN, Name, etc).

C#C#C#C#

C# C# C#C#

69

Modified Student Classusing System.Collections;public class Student {

public int USN;public string Name;public Student() {USN = 0; Name = null;}public Student(int USN, string Name) {

this.USN = USN;this.Name = Name;

}public class SortName : IComparer // helper class{

public SortName() {}int Compare(object o1, object o2){

Student s1 = (Student) o1;Student s2 = (Student) o2;return String.Compare(s1.Name, s2.Name);

}}

C#C#C#C#

C# C# C#C#

70

Using Multiple Sort Order System.Sort has a number of overloaded methods. One of them is to take

an object implementing IComparerstatic void Main(string[] args){

Student[] cseStd = new Student[3];cseStd[0] = new Student(111,"Scott");cseStd[1] = new Student(100,"Allen");cseStd[2] = new Student(45,"John");

try{

Array.Sort(cseStd, new SortName()); }catch(Exception e){

Console.WriteLine(e.StackTrace);}Console.WriteLine("Array after Sorting by Name:");foreach(Student s in cseStd)

Console.WriteLine(s.USN + " " + s.Name);}

}

C#C#C#C#

C# C# C#C#

71

Static Helper Class The helper classes may be staticpublic class car : IComparable

{ …public static IComparer class SortName

{ …. }}

// Calling program Array.Sort(cseStd, Student.SortName());

C#C#C#C#

C# C# C#C#

72

Interfaces of System.Collections Namespace Sytem.Collections defines a no. of interfaces like

ICollection Defines generic characterstics.

IEquality Comparer Defines method to support the comparison of objects for equality

IDictionary Allows an object to represent its contents using name/value pairs

IDictionaryEnumerator

Enumerates the contents of a type supporting IDictionary

IEnumerable Return the IEnumerator interface for a given object

IEnumerator Generally support foreach – style

IHashCodeProvider Returns hash code

IKeyComparer Combines the functionality of IComparer & IHashcodePRovider to allow object to be compared in a “hash-code-compatible manner”

IList Provides behavior to Add, Remove, & Index items in a list of objects.

C#C#C#C#

C# C# C#C#

73

Contd… Many of these interfaces are related by an interface hierarchy & some are stand

alone entities.

IDictionaryinterface

IEnumerableinterface

IListinterface

ICollectioninterface

IEnumeratorinterface

IDictionary IEnumeratorinterface

C#C#C#C#

C# C# C#C#

74

The Role of ICollection This defines a behavior supported by a collection type This provides a small set of properties that allows to

determine –a. the no. of items in the containerb. the thread safety of the container &c. the ability to copy the contents into a System.Array type

Icollection extends IEcnumerable Formal definitionpublic interface ICollection:IEnumerable{ int count { get; }

bool IsSynchronized { get; }object SyncRoot { get; }void CopyTo(Array array, int index);

}

C#C#C#C#

C# C# C#C#

75

The Role of IDictionary A Dictionary is a collection that maintains a set of name/value

pairs IDictionary interface defines a keys & values property as well

as Add(), Remove() & Contains() methods Formal definitionpublic interface IDictionary:ICollection,IEnumerable{ bool IsFixedSize { get; }

….ICollection keys { get; }ICollection values { get; }void Add (object key, object value);void clear();bool Contains (object key);void Remove( object key);

}

C#C#C#C#

C# C# C#C#

76

The Role of IDictionaryEnumerator IDictionary.GetEnumerator() returns an instance of the

IDictionaryEnumerator IDictionaryEnumerator is a strongly typed enumerator, it

extends IEnumerator Formal definitionpublic interface IDictionaryEnumerator:IEnumerator{ Dictionary Entry { get; }

object key { get; }object value { get; }

} Also able to traverse the name/value pairs using the

ke/value properties.

C#C#C#C#

C# C# C#C#

77

The Role of IList It provides ability to insert, remove & index items into ( or

out of ) a container Formal definitionpublic interface IList:IEnumerable{ bool IsFixedSize { get; }

……int Add (object value);int IndexOf(object value);void Insert( int index, object value)lvoid Remove(object value);Void RemoveAt(int index);}

C#C#C#C#

C# C# C#C#

78

System.Collections Namespace Sytem.Collections has many classes

ArrayList Dynamic array of objects

IList, ICollection, IEnumerable, & ICloneable

Hashtable collection of objects identified by keys

IDictionary, ICollection, IEnumerable, & ICloneable

Queue FIFO ICollection, IEnumerable, & ICloneable

SortedList Same as Dictionary, but accessed by index

IDictionary, ICollection, IEnumerable, & ICloneable

Stack LIFO ICollection and IEnumerable

C#C#C#C#

C# C# C#C#

79

ArrayList Basics The ArrayList is not guaranteed to be sorted. You must sort the

ArrayList prior to performing operations (such as BinarySearch) that require the ArrayList to be sorted.

The capacity of a ArrayList is the number of elements the ArrayList can hold. The default initial capacity for an ArrayList is 0. As elements are added to a ArrayList, the capacity is automatically increased as required through reallocation. The capacity can be decreased by calling TrimToSize or by setting the Capacity property explicitly.

Elements in this collection can be accessed using an integer index. Indexes in this collection are zero-based.

ArrayList accepts a null reference as a valid value and allows duplicate elements.

C#C#C#C#

C# C# C#C#

80

Exampleusing System; using System.Collections; public class SamplesArrayList {

public static void Main() { // Creates and initializes a new ArrayList.

ArrayList myAL = new ArrayList(); myAL.Add("Hello"); myAL.Add("World"); myAL.Add("!"); // Displays the properties and values of the ArrayList. Console.Write( "myAL" ); Console.WriteLine( " Count: {0}", myAL.Count ); Console.WriteLine( " Capacity: {0}", myAL.Capacity ); Console.Write( " Values:" ); PrintValues( myAL );

} public static void PrintValues( IEnumerable myList ) {

foreach ( Object obj in myList ) Console.Write( " {0}", obj ); Console.WriteLine();

}

myAL Count: 3

Capacity: 16

Values: Hello World !

C#C#C#C#

C# C# C#C#

81

System.ArrayList AddRange() populates the array with Cars// Create ArrayList and fill with some initial values.Console.WriteLine("***** Fun with ArrayList *****");ArrayList carArList = new ArrayList();carArList.AddRange(new Car[ ] { new Car("Fred", 90, 10), new Car("Mary", 100, 50), new Car("MB", 190, 0)});Console.WriteLine("Items in carArList: {0}", carArList.Count);

// Print out current values. foreach(Car c in carArList){

Console.WriteLine("Car pet name: {0}", c.PetName);}

C#C#C#C#

C# C# C#C#

82

System.ArrayList…. Index() is used to plug a new Car at any

position/index// Insert a new item.Console.WriteLine("-> Inserting new item");carArList.Insert(2, new Car("TheNewCar", 0, 0));Console.WriteLine("Items in carArList: {0}", carArList.Count);

// Get object array from ArrayList & print again.object[] arrayOfCars = carArList.ToArray();for(int i = 0; i < arrayOfCars.Length; i++){

Console.WriteLine("Car pet name: {0}", ((Car)arrayOfCars[i]).PetName);

}

C#C#C#C#

C# C# C#C#

83

System.Collections.Queue

Dequeue() – Delete and return first object from the Queue Enqueue() – Insert an object into the Queue Peek() – Return the first object without deleting

Console.WriteLine("\n***** Queue Demo *****");// Now make a Q with three itemsQueue carWashQ = new Queue();carWashQ.Enqueue(new Car("FirstCar", 0, 0));carWashQ.Enqueue(new Car("SecondCar", 0, 0));carWashQ.Enqueue(new Car("ThirdCar", 0, 0));

// Peek at first car in QConsole.WriteLine("First in Q is {0}",

((Car)carWashQ.Peek()).PetName);

C#C#C#C#

C# C# C#C#

84

System.Collections.Queue// Remove each item from Q

WashCar((Car)carWashQ.Dequeue());

WashCar((Car)carWashQ.Dequeue());

WashCar((Car)carWashQ.Dequeue());

// Try to de-Q again?

try

{

WashCar((Car)carWashQ.Dequeue());

}

catch(Exception e)

{ Console.WriteLine("Error!! {0}", e.Message);}

C#C#C#C#

C# C# C#C#

85

System.Collections.StackStack stringStack = new Stack();stringStack.Push("One");stringStack.Push("Two");stringStack.Push("Three");// Now look at the top item.Console.WriteLine("Top item is: {0}", stringStack.Peek());Console.WriteLine("Popped off {0}", stringStack.Pop());Console.WriteLine("Top item is: {0}", stringStack.Peek());Console.WriteLine("Popped off {0}", stringStack.Pop());Console.WriteLine("Top item is: {0}", stringStack.Peek());Console.WriteLine("Popped off {0}", stringStack.Pop());try{

Console.WriteLine("Top item is: {0}", stringStack.Peek());Console.WriteLine("Popped off {0}", stringStack.Pop());

}catch(Exception e){ Console.WriteLine("Error!! {0}\n", e.Message);}

C#C#C#C#

C# C# C#C#

86

End of Chapter 6