嗔秤戻幣�哉膵�云利匈嬉蝕湊蛸賜�塋床四衲���萩晦編報炎嘔囚^泡仟 ̄云利匈��
VB2008貫秘壇欺娼宥(PDF鯉塀哂猟井)-及79何蛍
酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何! 泌惚云慕短嗤堋響頼���誅卒亮茂�俊彭堋響��辛聞喘貧圭 "辺茄欺厘議箝誓匂" 孔嬬 才 "紗秘慕禰" 孔嬬��
Public WearsHats As Boolean
Public RunsSlowly As Boolean
End Class
In this definition�察�each attribute of PersonWithAttributes is its own data member。 Another
way to achieve the same effect is to consider each attribute as its own binary flag that is encoded
into PersonWithAttributes。 The class would be rewritten as follows�此�
Class PersonWithAttributes
Public Attributes As Integer
End Class
In the rewritten example�察�the Boolean attributes are encoded into the data member
Attributes using bitwise operators。
To encode a flag in a number means to tweak the individual binary bits of a number。 To
access the individual bits�察�you need to create constant numbers that are a power of 2。 We use a
´´´´´´´´´´´´´´´´´´´´´´Page 441´´´´´´´´´´´´´´´´´´´´´´´
CH AP T E R 1 6 * L E A R N I N G A B OU T O TH E R V IS U AL B A SI C T E C HN IQ U E S 419
power of 2 convention because binary is a counting system based on the power of 2。 Thus�察�the
three Boolean data members are converted to constants�此�
Const isTall As Integer = 1
Const wearsHats As Integer = 2
Const runsSlow As Integer = 4
Now you could create a person that is tall and runs slowly�察�like this�此�
Dim person As PersonWithAttributes = New PersonWithAttributes�┌�
person。Attributes = isTall Or runsSlow
The variable person。Attributes is assigned the operations of isTall and runsSlow。 So if
isTall is 0001�察�and runsSlow is 0100�察�taking the bitwise OR ��Or�� of the two values results in 0101。
A bitwise OR is when you pare two values�察�and if either value is nonzero�察�then the
answer is nonzero。 If you were to convert the binary number into a decimal number�察�you would
get the value of 5。 You could verify that the person isTall like this�此�
If ��person。Attributes And isTall�� 0 Then
Console。WriteLine�─�Person is tall;��
Else
Console。WriteLine�─�Person is not tall;��
End If
A bitwise shift is the shifting of the bits to the left or to the right by the number of places indi
cated by the shift。 The following code demonstrates shifting the bits two places to the left �─掘�2
The result is 2�察�which has the binary value 10。
For the most part�察�you probably will not use the binary shift operators。 Unless you are dealing
with hardware´related programming ��such as GUI interactions���察�whatever you can do with
flags can be replicated using a bination of Boolean types and structures。 However�察�when
you do encounter bitwise operators�察�you will recognize what they are doing。
Modulus
The modulus operator ��Mod�� is very useful when you want to perform division operations and
need to know how much is left over。 For example�察�the following calculation yields a value of 3。
Dim a As Integer = 17 / 5
´´´´´´´´´´´´´´´´´´´´´´Page 442´´´´´´´´´´´´´´´´´´´´´´´
420 CH AP T E R 1 6 * L E A R N I N G A B OU T O TH E R V IS U AL B A SI C TE C H N IQ U E S
Yet because it is an integer division�察�you don¨t know if the value is evenly divided by 5。 The
following calculation lets you figure out the remainder for the division。
Dim remainder As Integer = 17 Mod 5
Increment and Decrement
The increment �┌�=�� and decrement �─ �=�� operators are useful in place of the addition and subtrac
tion operators。 Visual Basic also has the *= and /= operators�察�which you can use in place of the
multiplication and division operators。 The idea behind these operators is to perform an operation
on the variable itself。
Let¨s say you execute this code�此�
Dim a As Integer = 2
a ��= 1
Then after the increment operation�察�the variable a will have a value of 3。
Overloading Operators
Suppose you want to implement a special type�察�such as a plex number type�察�and want to
support the �� sign。 To do so�察�you would need to implement the �� operator�察�which�察�in turn�察�over
loads the �� operator。
As an example�察�let¨s walk through implementing the �� operator for the plex number
type。 plex numbers are numbers that have two parts�此�real and imaginary。 For example�察�a �� b
is a plex number�察�where a is the real part and b is the imaginary part。 To add a plex
number�察�you add the real parts�察�and then add the imaginary parts�察�and that gives you the new
number。 The following is the plex number type�察�plexType�察�declaration。
Public NotInheritable Class plexType
Private ReadOnly _imaginary As Double
Private ReadOnly _real As Double
Public Sub New��ByVal real As Double�察�ByVal imaginary As Double��
_real = real
_imaginary = imaginary
End Sub
Public Overrides Function ToString�┌� As String
Return String。Concat��New Object�┌� ��;�─┌察�_real�察 ┌� �─┌察�_imaginary�察 ┌�i;����
End Function
Public ReadOnly Property Imaginary�┌� As Double
Get
Return _imaginary
End Get
End Property
´´´´´´´´´´´´´´´´´´´´´´Page 443´´´´´´´´´´´´´´´´´´´´´´´
CH AP T E R 1 6 * L E A R N I N G A B OU T O TH E R V IS U AL B A SI C T E C HN IQ U E S 421
Public ReadOnly Property Real�┌� As Double
Get
Return _real
End Get
Set��ByVal value As Double��
_real = value
End Set
End Property
End Class
plexType is an immutable type that has two data members representing the real and
imaginary number parts。
The goal is to define the �� operator so that the following code can be piled。
Dim a As plexType = New plexType��1。0�察�10。0��
Dim b As plexType = New plexType��2。0�察�20。0��
Dim c As plexType = a �� b
Overloading the �� operator means to add a method that has a special notation。 The following
is the modified plexType type with the overloaded operator implemented ��bolded��。
Public NotInheritable Class plexType
Private ReadOnly _imaginary As Double
Private ReadOnly _real As Double
Public Sub New��ByVal real As Double�察�ByVal imaginary As Double��
_real = real
_imaginary = imaginary
End Sub
Public Shared Operator ����ByVal a As plexType�察�ByVal b As plexType�� _
As plexType
Return New plexType�┌�a。Real �� b。Real���察。�a。Imaginary �� b。Imaginary����
End Operator
Public Overrides Function ToString�┌� As String
Return String。Concat��New Object�┌� ��;�─┌察�_real�察 ┌� �─┌察�_imaginary�察 ┌�i;����
End Function
Public ReadOnly Property Imaginary�┌� As Double
Get
Return _imaginary
End Get
End Property
´´´´´´´´´´´´´´´´´´´´´´Page 444´´´´´´´´´´´´´´´´´´´´´´´
422 CH AP T E R 1 6 * L E A R N I N G A B OU T O TH E R V IS U AL B A SI C TE C H N IQ U E S
Public ReadOnly Property Real�┌� As Double
Get
Return _real
End Get
End Property
End Class
The declaration of the overloaded operator is a specially defined function�察�which follows
these rules�此�
o The method is always declared as Shared in the context of the type。
o The method has a return type�察�which should be the type that you want to construct。 In
most cases�察�it is the type of the declaration ��except where a Boolean is required��。
o The method identifier starts with the keyword Operator�察�followed by a space�察�and then
the operator being overloaded �┌��察 ��察�and so on��。
The GoTo Statement
The GoTo statement allows you to jump from one spot in the code to another。 In the past�察�when
we did not have objects�察�methods�察�and other advanced programming constructs�察�developers
used the GoTo statement because they had no other choice。 Currently�察�many in the software
industry dislike the GoTo statement。 They think that the GoTo statement is a sign of poor program
ming�察�and that you never need to use it。 The Channel 9 forum ��http��//channel9。msdn。/
ShowPost。aspx��PageIndex=1&PostID=14652�� has a good discussion on the use of GoTo statements。
In this discussion�察�a person who was against the GoTo statement said this�此�
The only possible exception would be if you are doing some sort of puter graphics
app�察�where I would tolerate a ��for y�� ��for x�� nesting�察�because the inner loop is likely to be
quite simple and the structure makes more sense as an entirety。
So�察�he would tolerate the GoTo statement in a specific situation�察�and that means that one
can¨t argue that GoTo is all bad。
What I like about how Visual Basic implemented GoTo is that it is designed to solve a partic
ular problem�察�but not raise the old problems of spaghetti code making a mess of things。 So if
you need to use a GoTo statement�察�go ahead�察�just don¨t use it excessively。
One example where it is not easily possible to avoid using a GoTo statement is in the
following pseudo´code。
Do While FirstActionLoop�┌�
Do While SecondActionLoop�┌�
If BreakOutOfLoops�┌� Then
GoTo EXIT_ALL
End If
Loop
Loop
EXIT_ALL�此�
´´´´´´´´´´´´´´´´´´´´´´Page 445´´´´´´´´´´´´´´´´´´´´´´´
CH AP T E R 1 6 * L E A R N I N G A B OU T O TH E R V IS U AL B A SI C T E C HN IQ U E S 423
This code has two loops。 If the code is executing the second loop and decides to end pro
cessing�察�then exiting the loop bees a bit tricky�察�as you can break execution only one loop at a
time using the Exit Do statement。 Thus�察�one solution is to use the GoTo statement�察�as shown。
The GoTo statement is associated with an identifier that represents a label。 The label can be
placed almost anywhere in the declared method。 An exception is that you can¨t place a label in
a Select statement。 However�察�you can place the label before or after the GoTo keyword。
Generics Constraints
generics have been covered in several chapters。 An additional aspect of generics is
constraints�察�which can be optionally used to optimize programming。 Constraints limit the types
that the parameter can be。
Three types of constraints are Class�察�New�察�and a specific type。 As a general rule�察�a constraint
is added in the form of an As statement�察�as follows�此�
Class Example��Of DataType As ��New����
End Class
This example limits DataType to types that have a default constructor。
Using the Type Constraint
Type constraints allow you to associate a minimal type with the generics parameter。 For
example�察�suppose this interface is defined�此�
Interface IExample
Sub Method�┌�
End Interface
Adding an IExample constraint to the generics parameter allows you to define a class
as follows�此�
Class ExampleMgr��Of DataType As �� IExample����
Private _inst As DataType
Public Sub New��ByVal inst As DataType��
_inst = inst
End Sub
Public Sub DoSomething�┌�
_inst。Method�┌�
End Sub
End Class
In the example�察�the constraint of IExample allows a developer to call Method�┌�。 If the constraint
were not there�察�the reference to Method would generate a piler error�察�because Method�┌� is
not a method of DataType。
But is this ability to reference a method an advantage�拭�After all�察�you could write the
ExampleMgr code without using generics�察�like this�此�
´´´´´´´´´´´´´´´´´´´´´´Page 446´´´´´´´´´´´´´´´´´´´´´´´
424 CH AP T E R 1 6 * L E A R N I N G A B OU T O TH E R V IS U AL B A SI C TE C H N IQ U E S
Class ExampleMgr
Dim _inst As IExample
Public Sub New��ByVal inst As IExample��
Me。_inst = inst
End Sub
Public Sub DoSomething�┌�
_inst。Method�┌�
End Sub
End Class
The generics code and the interface´based code do the exact same thing�察�and using
generics offers no advantage in this example。 But that is not always the case。 Consider the
following modified example of ExampleMgr。
Class ExampleMgr��Of DataType As �� IExample ����
Dim _inst As DataType
Public Sub New��ByVal inst As IExample��
Me。_inst = CType��inst�察�DataType��
End Sub
Public Sub DoSomething�┌�
_inst。Method�┌�
End Sub
Public ReadOnly Property Inst�┌� As DataType
Get
Return _inst
End Get
End Property
End Class
With generics�察�you can write a property that contains a reference to the base type。 Had
you used the pure interface´based code�察�the Inst property would need to be of type IExample�察�and
to get the same effect as the generics example�察�a cast would be involved。 A cast is not the
end of the world�察�but it is inconvenient and not type´safe�察�since you don¨t know if a cast will
work until you execute the code。
You can add multiple interfaces and classes as constraints�察�although you are limited。 The
limitations are identical to the limitations when subclassing a class or interface�此�
o You can subclass only a sing
酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何!
梁椣戻幣�� 梁心弌傍議揖扮窟燕得胎��傍竃徭失議心隈才凪万弌誌育断蛍�輌臆惨軼僑〃�燕慕得珊辛參資誼持蛍才将刮襲潜��範寔亟圻幹慕得 瓜寡追葎娼得辛參資誼寄楚署衛、持蛍才将刮襲潜填��