Cover | Table of Contents
Class keyword for defining classes
and an Inherits keyword for object inheritance,
among others. Visual Basic 6 code can't be compiled by the
Visual Basic .NET compiler without significant modification. The good
news is that Microsoft has provided a migration tool to handle the
task (mostly, anyway). Code migration is explained in Appendix A. The Visual Basic .NET language itself is
detailed in Chapter 2.
The first program to write is the same for all languages: Print the words hello, world—Brian W. Kernighan and Dennis M. Ritchie, The C Programming Language
Imports System
Public Module Hello
Public Sub Main( )
Console.WriteLine("hello, world")
End Sub
End Modulevbc Hello.vb
vbc invokes the Visual Basic .NET
command-line compiler, which ships with the .NET Framework SDK, and
instructs it to compile the file named in the command-line argument.
Compiling Hello.vb generates the file
Hello.exe. After compiling, type
Hello at the command line to run your program.
Figure 1-1 shows the results of compiling and
running this program.
_
), may be of
any length, and after the first character must consist of only
alphanumeric and underscore characters. Namespace declarations may be
declared either with identifiers or qualified
identifiers
. Qualified identifiers consist of
two or more identifiers connected with the dot character (
.
). Only
namespace declarations may use qualified identifiers.
Imports System
Namespace ORelly.ProgVBNet
Public Class Hello
Public Shared Sub SayHello( )
Console.WriteLine("hello, world")
End Sub
End Class
End Namespace[]). Consider this code fragment:
Public Class [Public]
Public Shared Sub SayHello( )
Console.WriteLine("hello, world")
End Sub
End Class
Public Class SomeOtherClass
Public Shared Sub SomeOtherMethod( )
[Public].SayHello( )
End Sub
End Class|
Keyword
|
Description
|
|---|---|
AddHandler
|
Visual Basic .NET Statement
|
AddressOf
|
Visual Basic .NET Statement
|
Alias
|
Used in the
Declare statement |
And
|
Boolean operator
|
AndAlso
|
Boolean operator
|
Ansi
|
Used in the
Declare statement |
Append
|
Used as a symbolic constant in the FileOpen
function
|
As
|
Used in variable declaration (
Dim,
Friend, etc.)
|
Assembly
|
Assembly-level attribute specifier |
10 is a
literal, but x and y are not:
x = y * 10
10 in this code fragment is interpreted by the
compiler as type Integer because it is an integer that falls within
the range of the Integer type.
3.14 is a literal of type Double:
z = y * 3.14
"hello, world" is a literal of type
String:
Console.WriteLine("hello, world")' Wrong
Console.WriteLine("hello,
world")Dim x As Integer
Dim y As System.Int32
If x.GetType() Is y.GetType( ) Then
Console.WriteLine("They're the same type!")
Else
Console.WriteLine("They're not the same type.")
End IfPublic Class SomeClass ' ... End Class
Dim x As New SomeClass( ) x.DoSomething( )
' The namespace is "FooBarCorp.SuperFoo2100". Dim x As New FooBarCorp.SuperFoo2100.SomeClass( ) x.DoSomething( ) ' ... ' The namespace is "MegaBiz.ProductivityTools.WizardMaster". Dim y As New MegaBiz.ProductivityTools.WizardMaster.SomeClass( ) y.DoSomethingElse( )
.).
When looking at a fully qualified type name, everything prior to the
final period is the namespace name. The name after the final period
is the type name.
.
TechnologyName.
For example, "Microsoft.VisualBasic".
Namespace
keyword, like this:
Namespace MegaBiz.ProductivityTools.WizardMaster
Public Class SomeClass
' ...
End Class
End NamespacePublic Shared Function RemainingCarbonMass( _ ByVal InitialMass As Double, _ ByVal Years As Long _ ) As Double Return InitialMass * ((0.5 ^ (Years / 5730))) End Function
Years by
5730? In this code, 5730 is
referred to as a magic
number --
one whose meaning is not readily evident
from examining the code. The following changes correct this problem:
Public Const CarbonHalfLifeInYears As Double = 5730 Public Shared Function RemainingCarbonMass( _ ByVal InitialMass As Double, _ ByVal Years As Long _ ) As Double Return InitialMass * ((0.5 ^ (Years / CarbonHalfLifeInYears))) End Function
i whose type is Integer:
Dim i As Integer
Dim
indicates a variable declaration.
Dim is short for dimension
and dates back to the original days of the BASIC programming language
in the late 1960s. In that language, variables were not declared;
they were just used where needed (except for arrays). Because of how
arrays were laid out in memory, the BASIC language interpreter had to
be told of the dimensions of an array before the array was used. This
was the purpose of the Dim statement. In later
years, when declaration of all variables was agreed upon to be a
good thing, the use of the
Dim statement was broadened to include all
variable declarations.
Dim x%
Dim x As Integer
|
Data type
|
Type character
|
Example
|
|---|---|---|
|
Decimal
|
@
|
Dim decValue@ = 132.24
|
|
Double
|
#
|
Dim dblValue# = .0000001327
|
|
Integer
|
CoffeeBreaks.
Each declaration is invisible to the code in the other method. The
scope of each variable is the method in which it is declared.
Public Sub MyFirstMethod( ) Dim CoffeeBreaks As Integer ' ... End Sub Public Sub MySecondMethod( ) Dim CoffeeBreaks As Long ' ... End Sub
End,
Loop, or Next are local to that
block. For example:
Dim i As Integer
For i = 1 To 100
Dim j As Integer
For j = 1 To 100
' ...
Next
Next
' j is not visible herePublic
and Private are access modifiers:
Public Class SomeClass
Public Sub DoSomething( )
' ...
End Sub
Private Sub InternalHelperSub( )
' ...
End Sub
End Class|
Access modifier
|
Description
|
|---|---|
Friend
|
Defines a type that is accessible only from within the program in
which it is declared.
|
Private
|
Defines a type that is accessible only from within the context in
which it is declared. For instance, a Private variable declared
within a class module is accessible only from within that class
module. A Private class is accessible only from classes within which
it is nested.
|
Protected
|
Applies to class members only. Defines a type that is accessible only
from within its own class or from a derived class.
|
Protected Friend
|
Defines a type that is accessible from within the program in which it
is declared as well as from derived classes.
|
variable, field, or property = expression
Public Structure SomeStructure
Public MyPublicMember As String
End Structure
Public Class SomeClass
Public MyPublicMember As String
End Class
Public Class AssignmentTest
Public Shared Sub TestValueAndReferenceAssignment( )
Dim a, b As SomeStructure
Dim c, d As SomeClass
' Test assignment to value type.
a.MyPublicMember = "To be copied to 'b'"
b = a
a.MyPublicMember = "New value for 'a'"
Console.WriteLine("The value of b.MyPublicMember is """ _
& b.MyPublicMember & """")
' Test assignment to reference type.
c = New SomeClass( )
c.MyPublicMember = "To be copied to 'd'"
d = c
c.MyPublicMember = "New value for 'c'"
Console.WriteLine("The value of d.MyPublicMember is """ _
& d.MyPublicMember & """")
End Sub
End ClassThe value of b.MyPublicMember is "To be copied to 'b'" The value of d.MyPublicMember is "New value for 'c'"
-5). Binary operators (except
for one case) use infix
notation
, meaning that the operator is between
the operands (e.g., 1
+
2). The TypeOf...Is operator is
a binary operator that uses a special form that is neither prefix nor
infix notation.
+ (unary plus)- (unary minus)Dim sh As Short = -32768 Dim i As Integer = -sh
Not (logical negation)False, the result of
the operation is True, and vice versa.
AddressOf
AddressOf
operator returns a reference to a
method. Two different kinds of references can be obtained, depending
on the context in which the operator is used:
AddressOf operator is used within the
argument list of a call to a method, which is made available via the
_).
It must be the last character on its line, and it must be immediately
preceded by a space character. Lines connected in this way become a
single logical line. Here is an example:
Dim strSql As String = "SELECT Customers.CompanyName," _ & " COUNT(Orders.OrderID) AS OrderCount" _ & " FROM Customers INNER JOIN Orders" _ & " ON Customers.CustomerID = Orders.CustomerID" _ & " GROUP BY Customers.CompanyName" _ & " ORDER BY OrderCount DESC"
:) between the statements, like this:
i = 5 : j = 10
Option
statements, which affect the
behavior of the compiler. If used, they must appear before any
declarations in the same source file. They control the compilation of
the source code in the file in which they appear. They are:
Option
Compare
Option
Compare statement
controls the manner in which strings are compared to each other. The
syntax is:
Option Compare [ Binary | Text ]
Binary is specified, strings are compared based
on their internal binary representation (i.e., string comparisons are
case-sensitive). If Text is specified, strings are
compared based on case-insensitive alphabetical order. The default is
Binary.
Option
Explicit
Option
Explicit statement
determines whether the compiler requires all variables to be
explicitly declared. The syntax is:
Option Explicit [ On | Off ]
On is specified, the compiler requires all
variables to be declared. If Public Class Employee
Public EmployeeNumber As Integer
Public FamilyName As String
Public GivenName As String
Public DateOfBirth As Date
Public Salary As Decimal
Public Function Format( ) As String
Return GivenName & " " & FamilyName
End Function
End ClassDim emp As New Employee( )
emp.EmployeeNumber = 10
emp.FamilyName = "Rodriguez"
emp.GivenName = "Celia"
emp.DateOfBirth = #1/28/1965#
emp.Salary = 115000
Console.WriteLine("Employee Name: " & emp.Format( ))
Console.WriteLine("Employee Number: " & emp.EmployeeNumber)
Console.WriteLine("Date of Birth: " & emp.DateOfBirth.ToString("D", Nothing))
Console.WriteLine("Salary: " & emp.Salary.ToString("C", Nothing))Employee Name: Celia Rodriguez Employee Number: 10 Date of Birth: Thursday, January 28, 1965 Salary: $115,000.00
New
keyword. The New
keyword is, in effect, a unary operator that takes a type identifier
as its operand. The result of the operation is a reference to a newly
created object of the given type. Consider the following:
Interface statement:
Public Interface ISomeInterface
Sub SomeSub( )
Function SomeFunction( ) As Integer
Property SomeProperty( ) As String
Event SomeEvent( _
ByVal sender As Object, _
ByVal e As SomeEventArgs _
)
End InterfaceEnd
Sub, End
Function, or End
Property statements; or property get or set
blocks. There are no access modifiers (Public,
Private, etc.) because all members of an interface
are public by definition. By convention, interface names start with
the letter "I".
Public Class SomeClass
' This indicates that the class implements the methods,
' properties, and events of the ISomeInterface interface.
Implements ISomeInterface
' This method implements the SomeSub method of the
' ISomeInterface interface.
Private Sub SomeSub( ) Implements ISomeInterface.SomeSub
' ...
End Sub
' This method implements the SomeFunction method of the
' ISomeInterface interface.
Private Function SomeFunction( ) As Integer _
Implements ISomeInterface.SomeFunction
' ...
End Function
' This property implements the SomeProperty property of the
' ISomeInterface interface.
Private Property SomeProperty( ) As String _
Implements ISomeInterface.SomeProperty
Get
' ...
End Get
Set
' ...
End Set
End Property
' This event implements the SomeEvent event of the
' ISomeInterface interface.
Private Event SomeEvent( _
ByVal sender As Object, _
ByVal e As SomeEventArgs _
) Implements ISomeInterface.SomeEvent
End ClassPublic Structure Complex
' The IFormattable interface provides a generic mechanism for
' asking a value to represent itself as a string.
Implements IFormattable
' These private members store the value of the complex number.
Private m_RealPart As Double
Private m_ImaginaryPart As Double
' These fields provide potentially useful values, similar to the
' corresponding values in the Double type. They are initialized
' in the shared constructor. The ReadOnly modifier indicates that
' they can be set only in a constructor.
Public Shared ReadOnly MaxValue As Complex
Public Shared ReadOnly MinValue As Complex
' This is a shared constructor. It is run once by the runtime
' before any other access to the Complex type occurs. Note again
' that this is run only once in the life of the program--not once
' for each instance. Note also that there is never an access
' modifier on shared constructors.
Shared Sub New( )
MaxValue = New Complex(Double.MaxValue, Double.MaxValue)
MinValue = New Complex(Double.MinValue, Double.MinValue)
End Sub
' The RealPart property gives access to the real part of the
' complex number.
Public Property RealPart( ) As Double
Get
Return m_RealPart
End Get
Set(ByVal Value As Double)
m_RealPart = Value
End Set
End Property
' The ImaginaryPart property gives access to the imaginary part
' of the complex number.
Public Property ImaginaryPart( ) As Double
Get
Return m_ImaginaryPart
End Get
Set(ByVal Value As Double)
m_ImaginaryPart = Value
End Set
End Property
' This is a parameterized constructor allowing initialization of
' a complex number with its real and imaginary values.
Public Sub New( _
ByVal RealPart As Double, _
ByVal ImaginaryPart As Double _
)
m_RealPart = RealPart
m_ImaginaryPart = ImaginaryPart
End Sub
' This function computes the sum of two Complex values.
Public Shared Function Add( _
ByVal Value1 As Complex, _
ByVal Value2 As Complex _
) As Complex
Dim retval As Complex
retval.RealPart = Value1.RealPart + Value2.RealPart
retval.ImaginaryPart = Value1.ImaginaryPart + Value2.ImaginaryPart
Return retval
End Function
' This function computes the difference of two Complex values.
Public Shared Function Subtract( _
ByVal Value1 As Complex, _
ByVal Value2 As Complex _
) As Complex
Dim retval As Complex
retval.RealPart = Value1.RealPart - Value2.RealPart
retval.ImaginaryPart = Value1.ImaginaryPart - Value2.ImaginaryPart
Return retval
End Function
' This function computes the product of two Complex values.
Public Shared Function Multiply( _
ByVal Value1 As Complex, _
ByVal Value2 As Complex _
) As Complex
Dim retval As Complex
retval.RealPart = Value1.RealPart * Value2.RealPart _
- Value1.ImaginaryPart * Value2.ImaginaryPart
retval.ImaginaryPart = Value1.RealPart * Value2.ImaginaryPart _
+ Value1.ImaginaryPart * Value2.RealPart
Return retval
End Function
' This function computes the quotient of two Complex values.
Public Shared Function Divide( _
ByVal Value1 As Complex, _
ByVal Value2 As Complex _
) As Complex
Dim retval As Complex
Dim numerator1 As Double
Dim numerator2 As Double
Dim denominator As Double
numerator1 = Value1.RealPart * Value2.RealPart _
+ Value1.ImaginaryPart * Value2.ImaginaryPart
numerator2 = Value1.ImaginaryPart * Value2.RealPart _
- Value1.RealPart * Value2.ImaginaryPart
denominator = Value2.RealPart ^ 2 + Value2.ImaginaryPart ^ 2
retval.RealPart = numerator1 / denominator
retval.ImaginaryPart = numerator2 / denominator
Return retval
End Function
' This function implements IFormattable.ToString. Because it is
' declared Private, this function is not part of the Complex
' type's default interface. Note that the function name need
' not match the name as declared in the interface, nor need
' it be in the format shown here.
Private Function IFormattable_ToString( _
ByVal format As String, _
ByVal formatProvider As IFormatProvider _
) As String Implements IFormattable.ToString
Dim realFormatter As IFormattable = m_RealPart
Dim imaginaryFormatter As IFormattable = m_ImaginaryPart
Return realFormatter.ToString(format, formatProvider) & " + " _
& imaginaryFormatter.ToString(format, formatProvider) & "i"
End Function
' This function formats the Complex value as a string.
Public Overrides Function ToString( ) As String
Return CType(Me, IFormattable).ToString(Nothing, Nothing)
End Function
End Structure ' ComplexPublic Enum Rainbow Red Orange Yellow Green Blue Indigo Violet End Enum
Dim myRainbow As Rainbow = Rainbow.Blue
Dim myRainbow As Rainbow = Rainbow.Blue
Console.WriteLine("The value of myRainbow is: " & myRainbow.ToString( ))The value of myRainbow is: Blue
Dim myRainbow As Rainbow Dim yourRainbow As Rainbow ' ... If myRainbow < yourRainbow Then ' ... End If
For...Next statements. For example:
For myRainbow = Rainbow.Red To Rainbow.Violet ' ... Next
Public Enum MyLegacyErrorCodes NoError = 0 FileNotFound = -1000 OutOfMemory = -1001 InvalidEntry = -2000 End Enum
Dim x As Integer = 0 Dim y As Integer = 1 \ x
Try...End
Try blocks.
Example 2-9 shows how to catch the divide-by-zero
exception.
Try Dim x As Integer = 0 Dim y As Integer = 1 \ x Catch e As Exception Console.WriteLine(e.Message) End Try
Catch block. The Catch
statement declares a variable of type Exception that receives
information about the exception that occurred. This information can
then be used within the Catch block to record or
report the exception, or to take corrective action. The previous code
merely displays the message associated with the exception that
occurred, as shown here:
Attempted to divide by zero.
Catch block,
program execution continues with whatever follows the
End
Try statement. In
Try blocks in which no exception occurs, execution
continues through to the last statement of the Try
block and then skips the statements in the Catch
block.
Catch statement of
Example 2-9 is of type Exception (defined in the
System namespace). All exceptions are represented by types that
derive, either directly or indirectly, from the Exception type. The
Public Class EventProducer
Public Event SomeEvent( )
Public Sub DoSomething( )
' ...
RaiseEvent SomeEvent( )
' ...
End Sub
End ClassEvent statement in this code fragment declares
that this class is capable of raising an event called SomeEvent. The
empty parentheses in the declaration indicate that the event will not
pass any data. An example later in this section will show how to
define events that pass data.
RaiseEvent statement in the DoSomething method
raises the event. Any clients of the object that have registered
their desire to receive this event will receive it at this time.
Receiving an event means that a method will be called on the client
to handle the event. Here is the definition of a client class that
receives and handles events from the EventProducer class:
Public Class EventConsumer
Private WithEvents producer As EventProducer
Public Sub producer_SomeEvent( ) Handles producer.SomeEvent
Console.WriteLine("Hey, an event happened!!")
End Sub
Public Sub New( )
producer() = New EventProducer( )
End Sub
Public Sub DoSomething( )
' ...
producer().DoSomething( )
' ...
End Sub
End ClassModule statement, as shown here:
Public Module ModuleTest ' ... End Module