Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C# ПІДРУЧНИКИ / c# / Manning - Windows.forms.programming.with.c#.pdf
Скачиваний:
108
Добавлен:
12.02.2016
Размер:
14.98 Mб
Скачать

Now the project should compile with no errors in Visual Studio .NET. If you are not using Visual Studio, multiple files can be included in the library by simply providing the list of files to the compiler. An example of how this might look is shown here.

>csc /target:library /out:MyPhotoAlbum.dll PhotoAlbum.cs Photograph.cs /r:System.dll /r:System.Drawing.dll

Before we deal with the possible exception that can occur in the Photograph.Image property, let’s return to our PhotoAlbum class to make some initial use of the Photograph class.

5.3INTERFACES REVISITED

Back in our PhotoAlbum class, we are ready to implement the interfaces required. As you’ll recall, an interface defines the set of required members, but does not provide any implementation. Supporting an interface requires that we define the class as supporting the interface, and include the required members for that interface within the class.

For the PhotoAlbum class, the CollectionBase class defines itself as supporting the IEnumerable, ICollection, and IList interfaces. An implementation for the single method GetEnumerator required by the IEnumerable interface is provided by CollectionBase. As a result, we are left to implement the ICollection and IList interfaces. A list of ICollection members is provided in the following table:

PhotoAlbum members required for the ICollection interface

 

Name

Implementation Notes

 

 

 

 

Count

This property is provided by CollectionBase.

 

IsSyncronized

For simplicity, we will not provide a synchronized interface for

Properties

 

the PhotoAlbum class. As a result, this property will always

 

 

return false.

 

SyncRoot

 

 

 

 

Methods

CopyTo

 

 

 

 

The IList interface has a slightly longer list of members. Some of them are already provided by the CollectionBase class, but the bulk of them will be implemented using the protected CollectionBase.List property.

PhotoAlbum members required for the IList interface

 

Name

Implementation Notes

 

 

 

 

IsFixedSize

This method will always return false.

Properties

IsReadOnly

This method will always return false.

 

Item

This property enables array-style indexing for our class.

 

 

 

INTERFACES REVISITED

145

PhotoAlbum members required for the IList interface (continued)

 

Name

Implementation Notes

 

 

 

 

Add

 

 

Clear

This method is provided by CollectionBase.

 

Contains

 

Methods

IndexOf

 

 

Insert

 

 

Remove

 

 

RemoveAt

This method is provided by CollectionBase.

 

 

 

We will examine the implementation of these interfaces separately.

5.3.1SUPPORTING THE ICOLLECTION INTERFACE

The implementation of the ICollection members will use the protected List property from our base class, so let’s get to it. We will make these and our IList members virtual to allow any subclass to override them as needed.

Set the version number for the application to 5.3.

SUPPORT THE ICOLLECTION INTERFACE

 

Action

Result

 

 

 

1

Display the PhotoAlbum.cs file.

 

 

 

 

2

Implement the IsSynchronized

public virtual bool IsSynchronized

 

property.

{

 

 

get { return false; }

 

 

}

 

 

 

3

Implement the SyncRoot property.

public virtual object SyncRoot

 

 

{

 

 

get { return List.SyncRoot; }

 

 

}

 

 

 

4

Implement the CopyTo method.

public virtual void CopyTo

 

 

(Photograph[] array, int index)

 

 

{

 

 

List.CopyTo(array, index);

 

 

}

 

 

Note: We require the array parameter to be an

 

 

array of Photograph objects. The ICollection

 

 

interface defines the CopyTo method as

 

 

CopyTo(Array array, int index). Since a

 

 

Photograph[] is also an Array, our declaration

 

 

is an acceptable implementation even though it is

 

 

more restrictive than the method defined by the

 

 

interface.

 

 

 

5.3.2SUPPORTING THE ILIST INTERFACE

Our implementation for IList will be very similar in spirit to our implementation for ICollection. A key difference between the signatures of the IList members and

146

CHAPTER 5 REUSABLE LIBRARIES

our implementation is that we will use the Photograph class explicitly rather than the more generic object. Since a Photograph is still an object instance, a construct that requires an IList instance will still be able to use our PhotoAlbum object.

This may seem a bit boring and tedious, but it needs to be done for a complete implementation. Note that C# does not support C++ style templates at this time, which would have been handy for implementing this and other interfaces.

SUPPORT THE ILIST INTERFACE

 

Action

Result

 

 

 

1

Display the PhotoAlbum.cs file.

 

 

 

 

2

Implement the IsFixedSize

public virtual bool IsFixedSize

 

property.

{

 

 

get { return false; }

 

 

}

 

 

 

3

Implement the IsReadOnly

public virtual bool IsReadOnly

 

property.

{

 

 

get { return false; }

 

 

}

 

 

 

4

Implement the Item property.

public virtual Photograph this[int index]

 

Note: The Item property is the

{

 

get { return (Photograph)(List[index]); }

 

C# indexer, so we simply imple-

set { List[index] = value; }

 

ment indexing to support this

}

 

property.

 

 

 

 

5

Implement the Add method.

public virtual int Add(Photograph photo)

 

 

{

 

 

return List.Add(photo);

 

 

}

 

 

 

6

Implement the Contains

public virtual bool Contains(Photograph photo)

 

method.

{

 

 

return List.Contains(photo);

 

 

}

 

 

 

7

Implement the IndexOf

public virtual int IndexOf(Photograph photo)

 

method.

{

 

 

return List.IndexOf(photo);

 

 

}

 

 

 

8

Implement the Insert method.

public virtual void Insert

 

 

(int index, Photograph photo)

 

 

{

 

 

List.Insert(index, photo);

 

 

}

 

 

 

9

Implement the Remove method.

public virtual void Remove(Photograph photo)

 

 

{

 

 

List.Remove(photo);

 

 

}

 

 

 

These methods simply use the equivalent version in the protected List property, except that our implementation will only accept Photograph objects. The Item property is worth noting since it defines zero-based array-style indexing for our class, such as myAlbum[1] to specify the second Photograph in an album. The syntax

INTERFACES REVISITED

147

defines an indexer for the class. Indexers define array-style access to a class, using a syntax employing access methods similar to the declaration of properties. An indexer is defined using the this keyword to refer to the class itself, with the index variable defining the index value within the definition. In this manner the indexer defines retrieval and assignment access to the array of Photograph objects in the collection. Any collection class can be treated as an indexed array through the use of a similar indexer definition.

public virtual Photograph this[int index]

{

get { return (Photograph)(List[index]); } set ( List[index] = value; }

}

5.3.3IMPLEMENTING ALBUM POSITION OPERATIONS

This is a good place to insert the position operations for tracking the current location within an album. This position will be used by our application to display the current photo from the album as well as other tasks.

From a design perspective, we will use the word “Current” as a prefix for these operations. This is the name of a property used by the IEnumerator interface, and

is consistent with the meaning we intend here. We will add the following members to our class:2

PhotoAlbum position members

Member

Description

 

 

CurrentPosition property

Gets or sets the index of the current position within the album. By

 

definition, the first position is always zero (0), and the last position is

 

one less than the number of Photographs in the album.

CurrentPhoto property

Gets the Photograph object at the current position. This will use the

 

CurrentPosition property as an index into the collection to ensure

 

that we will always retrieve a valid photo.

CurrentNext method

Moves the current position to the next photograph. Returns a

 

boolean indicating if there was a next photo (true) or if the end of

 

the album has been reached (false).

CurrentPrevious method

Moves the current position to the previous photograph. Returns a

 

boolean indicating if there was a previous photo (true) or if the

 

beginning of the album has been reached (false).

 

 

2Some might argue for using the GetEnumerator method to track the position, or for creating a mechanism similar to database cursors to allow an application to track multiple locations within the album at the same time. The former is problematic if the application inserts or removes photos while the enumerator is active. The latter is a good idea, but a bit beyond what we intend to cover in this chapter.

148

CHAPTER 5 REUSABLE LIBRARIES

Соседние файлы в папке c#