C# Tutorial MSM_Murach chapter-15-slides

38
Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 1 C hapter15 How to w ork w ith interfaces and generics

Transcript of C# Tutorial MSM_Murach chapter-15-slides

Page 1: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 1

Chapter 15

How to work with interfaces and generics

Page 2: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 2

Objectives Applied 1. Use .NET interfaces as you develop the classes for an application. 2. Develop and use your own interfaces.

Knowledge 1. Distinguish between an interface and an abstract class. 2. Describe the use of the .NET ICloneable, IComparable<>, and

IEnumerable<> interfaces. 3. In general terms, describe the use of generic interfaces.

Page 3: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 3

The IDisplayable interface interface IDisplayable { string GetDisplayText(string sep); }

Page 4: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 4

A Product class that implements the IDisplayable interface

public class Product : IDisplayable { public string Code { get; set; } public string Description { get; set; } public decimal Price { get; set; } public Product(string Code, string Description, decimal Price) { this.Code = Code; this.Description = Description; this.Price = Price; } public string GetDisplayText(string sep) { return this.Code + sep + this.Description + sep + this.Price.ToString("c"); } }

Page 5: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 5

Code that uses the IDisplayable interface IDisplayable product = new Product("CS10", "Murach's C# 2010", 54.5m); Console.WriteLine(product.GetDisplayText("\n"));

Page 6: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 6

A comparison of interfaces and abstract classes Both interfaces and abstract classes provide signatures for

properties and methods that a class must implement. All of the members of an interface are abstract. In contrast, an

abstract class can implement some or all of its members. A class can inherit only one class (including abstract classes), but

a class can implement more than one interface. Interfaces can’t declare static members, but abstract classes can.

Page 7: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 7

Commonly used .NET interfaces Interface Members ICloneable object Clone() IComparable int CompareTo(object) IConvertible TypeCode GetTypeCode()

decimal ToDecimal() int ToInt32() (etc.)

IDisposeable void Dispose()

Page 8: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 8

Commonly used .NET interfaces for collections Interface Members IEnumerable IEnumerator GetEnumerator() IEnumerator object Current

bool MoveNext() void Reset()

ICollection int Count bool IsSynchronized object SyncRoot void CopyTo(array, int)

IList [int] void Remove(object) int Add(object) void RemoveAt(int) void Clear()

IDictionary [int] int Add(object) ICollection Keys void Remove(object) ICollection Values void Clear()

Page 9: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 9

The syntax for creating an interface public interface InterfaceName { type MethodName(parameters); // Declares a method type PropertyName // Declares a property { [get;] // Declares a get accessor [set;] // Declares a set accessor } ... }

Page 10: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 10

An interface that defines one method public interface IDisplayable { string GetDisplayText(string sep); }

An interface that defines two methods and a property

public interface IPersistable { object Read(string id); bool Save(object o); bool HasChanges { get; set; } }

Page 11: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 11

The syntax for creating an interface that inherits other interfaces public interface InterfaceName : InterfaceName1 [, InterfaceName2...] { interface members... }

An interface that inherits two interfaces public interface IDataAccessObject : IDisplayable, IPersistable { // add additional members here }

Page 12: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 12

The syntax for implementing an interface public class ClassName : [BaseClassName,] InterfaceName1 [, InterfaceName2]...

A Product class that implements ICloneable public class Product : ICloneable

A Product class that implements two interfaces public class Product : ICloneable, IDisplayable

A class that inherits a class and implements two interfaces

public class Book : Product, ICloneable, IDisplayable

Page 13: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 13

The prompt that’s displayed when you enter an interface name

The code that’s generated when you implement the interface

#region ICloneable Members public object Clone() { throw new Exception( "The method or operation is not implemented."); } #endregion

Page 14: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 14

The code that’s generated when you explicitly implement the interface

#region ICloneable Members object ICloneable.Clone() { throw new Exception( "The method or operation is not implemented."); } #endregion

Page 15: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 15

The code for the cloneable Product class public class Product : IDisplayable, ICloneable { public string Code { get; set; } public string Description { get; set; } public decimal Price { get; set; } public Product(string Code, string Description, decimal Price) { this.Code = Code; this.Description = Description; this.Price = Price; } #region IDisplayable Members

Page 16: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 16

The code for the cloneable Product class (cont.) public string GetDisplayText(string sep) { return this.Code + sep + this.Description + sep + this.Price.ToString("c"); } #endregion #region ICloneable Members public object Clone() { Product p = new Product(); p.Code = this.Code; p.Description = this.Description; p.Price = this.Price; return p; } #endregion }

Page 17: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 17

Code that creates and clones a Product object Product p1 = new Product("JAV5", "Murach's Beginning Java 2, SDK 5", 52.50m); Product p2 = (Product)p1.Clone(); p2.Code = "JSE6"; p2.Description = "Murach's Java SE 6"; Console.WriteLine(p1.GetDisplayText("\n") + "\n"); Console.WriteLine(p2.GetDisplayText("\n") + "\n");

The output that’s displayed by this code JAV5 Murach's Beginning Java 2, SDK 5 $52.50 JSE6 Murach's Java SE 6; $52.50

Page 18: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 18

A CreateList method that uses an interface as a parameter

public static List<object> CreateList(ICloneable obj, int count) { List<object> objects = new List<object>(); for (int i = 0; i < count; i++) { object o = obj.Clone(); objects.Add(o); } return objects; }

A WriteToConsole method that uses an interface as a parameter

public static void WriteToConsole(IDisplayable d) { Console.WriteLine(d.GetDisplayText("\n") + "\n"); }

Page 19: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 19

Code that uses the methods Product product = new Product("CS10", "Murach's C# 2010", 54.50m); List<object> products = CreateList(product, 3); foreach (Product p in products) { WriteToConsole(p); }

The output displayed by this code CS10 Murach's C# 2010 $54.50 CS10 Murach's C# 2010 $54.50 CS10 Murach's C# 2010 $54.50

Page 20: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 20

A CustomList<> class that uses generics public class CustomList<T> { private List<T> list = new List<T>(); // an Add method public void Add(T item) { list.Add(item); } // a read-only indexer public T this[int i] { get { return list[i]; } }

Page 21: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 21

A CustomList<> class that uses generics (cont.) // a read-only property public int Count { get { return list.Count; } } // the ToString method public override string ToString() { string listString = ""; for (int i = 0; i < list.Count; i++) { listString += list[i].ToString() + "\n"; } return listString; } }

Page 22: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 22

Code that uses the CustomList<> class // Test 1 Console.WriteLine("List 1 - ints"); CustomList<int> list1 = new CustomList<int>(); int i1 = 11; int i2 = 7; list1.Add(i1); list1.Add(i2); Console.WriteLine(list1.ToString()); // Test 2 Console.WriteLine("List 2 - Products"); CustomList<Product> list2 = new CustomList<Product>(); Product p1 = new Product("VB10", "Murach's Visual Basic 2010", 54.50m); Product p2 = new Product("CS10", "Murach's C# 2010", 54.50m); list2.Add(p1); list2.Add(p2); Console.Write(list2.ToString());

Page 23: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 23

Output that results from the Test 1 & Test 2 code List 1 - ints 11 7 List 2 - Products VB10 Murach's Visual Basic 2010 $54.50 CS10 Murach's C# 2010 $54.50

Page 24: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 24

A commonly used generic .NET interface Interface Members IComparable<> int CompareTo(T)

Page 25: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 25

Commonly used .NET interfaces for generic collections Interface Members IEnumerable<> IEnumerator<T>

GetEnumerator() ICollection<> int Count

bool IsReadOnly T SyncRoot Add(T) void Clear() bool Contains(T) void CopyTo(array, int) bool Remove(T)

Page 26: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 26

Commonly used .NET interfaces for generic collections (cont.) Interface Members IList<> [int]

int IndexOf(T) void Insert(int, T) void RemoveAt(int)

IDictionary<> [int] ICollection<K> Keys ICollection<V> Values void Add(K, V) bool ContainsKey(K) bool Remove(K) bool TryGetValue(K, V)

Page 27: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 27

A class that implements the IComparable<> interface

public class Product : IComparable<Product> { public string Code { get; set; } public string Description { get; set; } public decimal Price { get; set; } // other members #region IComparable<Product> Members public int CompareTo(Product other) { return this.Code.CompareTo(other.Code); } #endregion }

Page 28: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 28

Code that uses the Product class Product p1 = new Product("VB10", "Murach's Visual Basic 2010", 54.50m); Product p2 = new Product("CS10", "Murach's C# 2010", 54.50m); int compareValue = p1.CompareTo(p2); if (compareValue > 0) Console.WriteLine("p1 is greater than p2"); else if (compareValue < 0) Console.WriteLine("p1 is less than p2"); else if (compareValue == 0) Console.WriteLine("p1 is equal to p2");

Page 29: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 29

Values that can be returned by the CompareTo method Value Meaning -1 The current element is less than the compare element. 0 The current element is equal to the compare element. 1 The current element is greater than the compare element.

Page 30: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 30

A class that uses a constraint public class CustomList<T> where T: class, IComparable<T> { private List<T> list = new List<T>(); // an Add method that keeps the list sorted public void Add(T item) { if (list.Count == 0) { list.Add(item); } else { for (int i = 0; i < list.Count; i++) { T currentItem = list[i]; T nextItem = null; if (i < list.Count - 1) { nextItem = list[i + 1]; }

Page 31: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 31

A class that uses a constraint (cont.) int currentCompare = currentItem.CompareTo(item); if (nextItem == null) { if (currentCompare >= 0) { list.Insert(i, item); // insert before current item break; } ... ...

Page 32: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 32

Keywords that can be used to define constraints Keyword Description class The type argument must be a class. struct The type argument must be a structure. new() The type argument must have a default constructor.

You can’t use this keyword when the type argument must be a structure.

A class that uses constraints public class StructList<T> where T: struct

Another class that uses constraints public class ProductList<T> where T: Product, IComparable<T>, new()

Page 33: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 33

A class that implements the IEnumerable<> interface public class CustomList<T> : IEnumerable<T> { private List<T> list = new List<T>(); // other members #region IEnumerable<T> Members public IEnumerator<T> GetEnumerator() { foreach (T item in list) { yield return item; } } #endregion

Page 34: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 34

A class that implements the IEnumerable<> interface (cont.) #region IEnumerable Members System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw new Exception( "The method or operation is not implemented."); } #endregion }

Page 35: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 35

Code that uses the CustomList class Product p1 = new Product("VB10", "Murach's Visual Basic 2010", 54.50m); Product p2 = new Product("CS10", "Murach's C# 2010", 54.50m); CustomList<Product> list = new CustomList<Product>(); list.Add(p1); list.Add(p2); foreach (Product p in list) { Console.WriteLine(p.ToString()); }

Page 36: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 36

An interface named IGenericPersistable<> that uses generics

interface IGenericPersistable<T> { T Read(string id); bool Save(T obj); bool HasChanges { get; set; } }

Page 37: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 37

A class that implements the IGenericPersistable<> interface class Customer : IGenericPersistable<Customer> { // other members #region IGenericPersistable<Customer> Members public Customer Read(string id) { throw new Exception( "The method or operation is not implemented."); } public bool Save(Customer obj) { throw new Exception( "The method or operation is not implemented."); }

Page 38: C# Tutorial MSM_Murach chapter-15-slides

Murach’s C# 2010, C15 © 2010, Mike Murach & Associates, Inc. Slide 38

A class that implements the IGenericPersistable<> interface (cont.) public bool HasChanges { get { throw new Exception( "The property is not implemented."); } set { throw new Exception( "The property is not implemented."); } } #endregion }