梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈��梓囚徒貧議 Enter 囚辛指欺云慕朕村匈��梓囚徒貧圭�鮗� ● 辛指欺云匈競何��
!!!!隆堋響頼��紗秘慕禰厮宴和肝写偬堋響��
expect objects will work without the Visual Basic piler generating errors。 The If statement
said that the input type is a String�察�and destination type is a Double。 Thus�察�the methods CStr�┌�
and Double。Parse�┌� are called to convert the input string to a double number。 Once the string´to
double functions have pleted�察�the CellState could be assigned�察�if it were not for the little
problem of the generics´type level parameter。 The next steps of casting using CType�┌� and
DirectCast�┌� are a boxing and unboxing of a value type。 This is necessary because the piler
considers everything as an object�察�and thus you need to first convert to an object and then
convert to the actual type。
*Note The steps to convert from one generics type to another generics type would seem
cumbersome�察�and to a degree they are。 Although the steps illustrated here are the minimum�察�they allow you
to convert one type to another。 The steps are dangerous in that if you don¨t know ahead of time whether the
conversion is allowed�察�an exception could result。 In the example�察�an exception is almost impossible because
the types were checked ahead of time�察�and an appropriate plan of action was taken。
Overall�察�the AssignCellState��Of ���┌� method with generics parameters provides the
ability to cleanly assign a value to the spreadsheet�察�and a clean and maintainable method to
perform a conversion。 This goes back to the original requirement of being able to mix types safely。
Overriding the ToString�┌� Functionality
Debugging a data structure like a spreadsheet is a fairly plex task�察�because there is too
much data。 The Worksheet��Of �� class implements the ToString�┌� method and generates a
string。 The string can be retrieved and then displayed using a method like Console。WriteLine�┌�。
´´´´´´´´´´´´´´´´´´´´´´Page 330´´´´´´´´´´´´´´´´´´´´´´´
308 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
Here is the implementation of worksheet¨s ToString�┌� function。
Public Overrides Function ToString�┌� As String
Dim builder As New StringBuilder�┌�
Dim row As Integer
For row = 0 To Cells。GetLength��0�� 1
Dim needma As Boolean = False
If _generateRowCounter Then
needma = True
builder。Append��row��
End If
Dim col As Integer
For col = 0 To Cells。GetLength��1�� 1
If needma Then
builder。Append�─┌察┌�
Else
needma = True
End If
If ellState��row�察�col�� IsNot Nothing Then
builder。Append��CellState��row�察�col��。ToString��
End If
Next col
builder。Append��ChrW��10����
Next row
Return builder。ToString
End Function
Because the worksheet can be large�察�StringBuilder is used to incrementally build a string
that is returned。
*Note The ToString�┌� method is useful when you¨re debugging or trying to perform analysis of the state
of an object without actually debugging the program。 Thus�察�for improved debugging or runtime analysis�察�always
implement ToString�┌�。
Using the Spreadsheet
With the interfaces and implementations plete�察�it is possible to use the spreadsheet。 The
sample application is a spreadsheet that calculates the average of a set of numbers and then
calculates how far each number is from the average。
Calculating an Average
The spreadsheet calculates the average of a set of numbers�察�and then subtracts the average
from each number。 The example demonstrates reading a plete spreadsheet to get a number
and reading individual elements to perform a calculation。
´´´´´´´´´´´´´´´´´´´´´´Page 331´´´´´´´´´´´´´´´´´´´´´´´
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 309
Let¨s use the following numbers to calculate the average。
Dim items As Double�┌� = New Double�┌� �� 1。0�察�2。0�察�3。0 ��
The average number is 2。0�察�and if you subtract the average from each number�察�you will get
the series �C1�察�0�察�and 1。
To make this work for a spreadsheet�察�the first step is to declare and then populate an
IWorksheet��Of BaseType�� instance。 To instantiate an IWorksheet��Of BaseType�� instance�察�you
use a factory that will instantiate the Worksheet��Of BaseType�� class。 The code looks like this�此�
Dim sheetAverage As IWorksheet��Of Double�� = _
SpreadsheetManager。CreateEmptyWorksheet��Of Double���──┌�
Dim items As Double�┌� = New Double�┌� ��1�察�2�察�3��
sheetAverage。Dimension�┌�items。Length �� 10���察�3��
For row = 0 To items。Length 1
sheetAverage。SetCellState��row�察�0�察�items��row����
Next row
The worksheet is declared as being of type Double ��IWorksheet��Of Double�����察�allowing you
to manage a Double value。 To populate sheetAverage�察�the numbers are iterated in a For loop
and assigned to the worksheet using the SetCellState�┌� method。 The method Dimension�┌� is
needed to create a fixed´length worksheet。
With the worksheet populated�察�to make sure everything looks right�察�you could call the method
ToString�┌� and see if all is as expected。
The next step is to assign the lambda expressions that will be used to calculate the average
and then the individual differences from the average。 When you assign a calculation to the work
sheet�察�you need to know whether the lambda expression will be stateful or stateless。 Remember
that lambda expressions have some state。 It is just a question of whether you want a shared
state lambda expression or an individual´state lambda expression。 In the case of the lambda
expressions for the average calculations�察�a shared state is acceptable。
To calculate the average�察�you use a technique where the average calculation is the last element
in the series of the array calculations。 Thus�察�when the average calculation is called�察�it knows
how many elements there are because of the row in which the average calculation is stored。
Function Average��ByVal worksheet As IWorksheet��Of Double���察�_
ByVal cellRow As Integer�察�ByVal cellCol As Integer��
Dim runningTotal As Double = 0
Dim row As Integer
For row = 0 To cellRow 1
runningTotal = ��runningTotal �� worksheet。GetCellState��row�察�0����
Next row
Return ��runningTotal / CDbl��cellRow����
End Function
。 。 。
sheetAverage。AssignCellCalculation��items。Length�察�0�察�AddressOf Average��
In the example�察�the average is calculated by using the variable cellRow as a maximum row。
Every cell ��GetCellState�┌��� before cellRow is added to a running total ��runningTotal���察�and then�察 �
finally�察�an average is returned by dividing runningTotal by cellRow。
´´´´´´´´´´´´´´´´´´´´´´Page 332´´´´´´´´´´´´´´´´´´´´´´´
310 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
With the average calculated�察�the next step is to calculate the difference between the average
and the individual items。 The result will be stored in a column to the right of the item cell state。
This is done by subtracting the average calculation cell state from the item value�察�as follows�此�
For row = 0 To items。Length 1
sheetAverage。AssignCellCalculation��row�察�1�察�_
F