按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
End Get
End Property
Public ReadOnly Property OneLeft() As SheetCoordinate
Get
Return New SheetCoordinate(Me。Row; (Me。Column 1))
End Get
End Property
Public ReadOnly Property OneRight() As SheetCoordinate
Get
Return New SheetCoordinate(Me。Row; (Me。Column + 1))
End Get
End Property
End Structure
In the declaration of SheetCoordinate; notice that Structure is used rather than Class。
We could have used a class; but SheetCoordinate serves the purpose of being a piece of data。
SheetCoordinate is a type where you store information that is used by another type。 A data type
might do some processing; but only to make it easier to manipulate the data。 For example;
notice how SheetCoordinate has properties to generate a new instance of SheetCoordinate that
might be one row higher or lower; or a column to the right or left。
The next step is to extend the worksheet definition and use generics to define the
type of worksheet。 The following is the plete definition of the IWorksheet。 These methods
…………………………………………………………Page 319……………………………………………………………
CH AP T E R 1 1 ■ L E A R N IN G AB O U T 。 N E T G E N E R I CS 297
are used to calculate the values of cells in the worksheet and work with the contents of individual
cells (the state of those cells)。 We can also assign the function that carries out the calculation of
a cell’s contents; using either a SheetCoordinate type or the row and column coordinates。
Public Interface IWorksheet(Of BaseType)
Inherits IWorksheetBase
Sub AssignCellCalculation(ByVal coords As SheetCoordinate; _
ByVal cb As Func(Of IWorksheet(Of BaseType); Integer; Integer; BaseType))
Sub AssignCellCalculation(ByVal row As Integer; ByVal col As Integer; _
ByVal cb As Func(Of IWorksheet(Of BaseType); Integer; Integer; BaseType))
Sub AssignColCalculation(ByVal col As Integer; _
ByVal cb As Func(Of IWorksheet(Of BaseType); _
Integer; Integer; BaseType))
Sub Calculate()
Function Calculate(ByVal coords As SheetCoordinate) As BaseType
Function Calculate(ByVal row As Integer; ByVal col As Integer) As BaseType
Sub CalculateCol(ByVal col As Integer)
Sub CalculateRow(ByVal row As Integer)
Function GetCellState(ByVal coords As SheetCoordinate) As BaseType
Function GetCellState(ByVal row As Integer; ByVal col As Integer) As BaseType
Sub SetCellState(ByVal coords As SheetCoordinate; ByVal val As BaseType)
Sub SetCellState(ByVal row As Integer; ByVal col As Integer; _
ByVal val As BaseType)
ReadOnly Property Data() As BaseType (;)
End Interface
The declaration of IWorksheet is as a generics type; where BaseType is a generics
parameter that represents the type of the spreadsheet。 Since IWorksheet is a type of spreadsheet;
it subclasses the IWorksheetBase interface; allowing IWorksheet to be part of a mixed collection
of IWorksheet instances。 The IWorksheet interface is fairly plex and contains many methods。
However; here we are focusing on the interface concept; rather than the individual methods。
Look at the bolded parts and notice how the interface is specific about the operations; but
vague about the type used in the operations。 This is what you want to achieve when using
generics。 You want to take a high…level approach and indicate which operations are available;
but leave out the types being manipulated in the operations。 The types will be specified later by
another programmer。
…………………………………………………………Page 320……………………………………………………………
298 CH AP T E R 1 1 ■ L E A R N I N G A B OU T 。 N E T G E N E R I CS
■Note The technique of having a generics type (such as IWorksheet) subclass a non… generics
type (such as IWorksheetBase) allows you to identify the general type that you are trying to describe with
some specialization in the generics type declaration。
Defining the IWorkbook Interface
Now that we’ve pleted the IWorksheet(Of BaseType) and IWorksheetBase interfaces; we
can define the workbook interface。 The workbook interface will not be a generics type;
since a workbook will contain multiple worksheet types。 However; as you will see; we can optimize
this interface to make it easier to use the workbook。
For the moment; let’s consider the plain…vanilla IWorkbook interface with no generics
types; which is defined as follows in the ServerSideSpreadsheet:
Imports System。Reflection
Imports Devspace。Trader。mon
_
Public Interface IWorkbook
Inherits IDebug
ReadOnly Property Identifier() As String
Default Property Item(ByVal identifier As String) As IWorksheetBase
End Interface
The IWorkbook interface defines an Identifier property and a default property Item。 Notice
how the attribute DefaultMember is defined to indicate the default property identifier (it is from
the System。Reflection namespace)。 Any class that implements IWorkbook is expected to contain
multiple references to IWorksheet(Of BaseType) instances。 How those references are managed
is not the responsibility of the IWorkbook interface; but of the IWorkbook interface implementation。
■Note The IWorkbook interface does not provide a Clear() method to reset the workbook and delete all
of the referenced worksheets。 It would seem logical to have a Clear() method; but in a garbage…collected
environment; that’s pletely unnecessary。 If you don’t want to use a workbook anymore; just don’t refer
ence it; and the garbage collector will take care of the rest。 Think of it as having the option of serving dinner
to your guests on real plates or paper plates。 Real plates might seem better; but they break and you need to
wash them。 Paper plates are used once and thrown away。 Of course; with paper plates you have recycling
issues that you don’t have in ; because the memory is recycled for you。
The property Identifier identifies the workbook represented by the current IWorkbook
object。 The identifier might be a path or file name and is pletely dependent on the imple
mentation of IWorkbook。
…………………………………………………………Page 321……………………………………………………………
CH AP T E R 1 1 ■ L E A R N IN G AB O U T 。 N E T G E N E R I CS 299
The default property; Item; is the primary way of getting and retrieving worksheets; where
each worksheet is referenced using a string identifier。 The identifier does not need to be a string—
it could have been a custom type; enumeration; or interface that is implemented。 Using a string
keeps things simple; but there are maintenance issues。
Let’s say all workbooks have a configuration worksheet。 So for most of the code; the string
identifier 〃configuration〃 is used。 However; a new programmer decides to use 〃Configuration〃
(with a capital C)。 This slight change will cause problems because 〃configuration〃 is meant to
have a lowercase c。 Here’s the example:
Dim workbook As IWorkbook
Dim works