By Matthew MacDonald
Book Price: $29.95 USD
£17.50 GBP
PDF Price: $23.99
Cover | Table of Contents | Colophon
Pmt( )
function.
txtInterestRate,
txtYears, txtFutureValue, and
txtMonthlyPayment (from top to bottom). Then, add
a button with the following event handler:Private Sub btnCalculate_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnCalculate.Click
Dim InterestRate, Years, FinalValue, MonthlyPayment As Double
InterestRate = Val(txtInterestRate.Text)
FinalValue = Val(txtFutureValue.Text)
MonthlyPayment = Pmt(InterestRate / 12 / 100, _
Years * 12, 0, -FinalValue, DueDate.BegOfPeriod)
txtMonthlyInvestment.Text = MonthlyPayment.ToString("C")
End SubMonthlyPayment value. One way to discover the
source of the problem is to move the mouse over all the parameters in
the statement and verify that they reflect what you expect. In this
case, the problem is that the ToString( ) method, which
more often than not was simply the fully qualified name of the class
itself. Moreover, you couldn't see the content of
public properties and indexers. The Watch and Locals windows provided
some improvement, but they weren't quite as
convenient or intuitive. Visual Studio 2005 changes the picture with
a new feature called debugger DataTips.Public Class Employee
Private _ID As String
Public ReadOnly Property ID( ) As String
Get
Return _ID
End Get
End Property
Private _Name As String
Public ReadOnly Property Name( ) As String
Get
Return _Name
End Get
End Property
Public Sub New(ByVal id As String, ByVal name As String)
_ID = id
_Name = name
End Sub
End Class
Public Class Department
Private _Manager As Employee
Public ReadOnly Property Manager( ) As Employee
Get
Return _Manager
End Get
End Property
Private _DepartmentName As String
Public ReadOnly Property Name( ) As String
Get
Return _DepartmentName
End Get
End Property
Public Sub New(ByVal departmentName As String, ByVal manager As Employee)
_DepartmentName = departmentName
_Manager = manager
End Sub
End ClassPrivate Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim XMLText As String = My.Computer.FileSystem.ReadAllText( _
"c:\FileDoesNotExist")
End Sub
PropertyGrid showing all the
information of the associated exception object. This change alone is
a great step forward from Visual Studio .NET 2003, where you needed
to write a Catch exception handler and set a
breakpoint to take a look at the underlying exception object.FirstName. If you use
search-and-replace, you'll also inadvertently affect
a text box named txtFirstName, an event handler
named cmdFirstName_Click, a database field
accessed through row("FirstName"), and even your
code comments. With symbolic rename, the IDE takes care of renaming
just what you want, and it completes all of its work in a single
step.TextBox1 and a button named
cmdText. Finally, add the form code in Example 1-2.Public Class TextTest
Private Sub TextTest_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
' Get the text from the text box.
Dim Text As String = TextBox1.Text
' Convert and display the text.
Text = ConvertText(Text)
MessageBox.Show("Uppercase Text is: " & Text)
End Sub
Public Function ConvertText(ByVal Text As String) As String
Return Text.ToUpper( )
End Function
End ClassAttribute class.Catch
block, the IntelliSense list will show only classes that derive from
the base Exception class (as shown in Figure 1-8). Select the Common or All tab at the bottom
of the list, depending on whether you want to see the most commonly
used classes or every possibility.
Text property in the
Properties window one at a time. Although this approach
isn't necessarily awkward, it certainly
isn't as easy as it could be. In Visual Studio 2005,
you can adjust a single property for a series of controls directly on
the form.Name property is selected, but Figure 1-10 shows an example with the
Text property.
Public Shared Function AddNumbers(ByVal A As Integer, _
ByVal B As Integer) As Integer
Return A + B
End Sub? (a shorthand for Print, which instructs Visual
Studio to display the result). You can enter the rest of the
statement like any other line of code, with the benefit of
IntelliSense. Figure 1-11 shows an example in which
the Command window is used to run the shared method just shown.
''' <summary>This is the summary.</summary>
<summary>
<remarks>
<param>
<param> tag for each
parameter.<returns>My objects provide easy access to various features
that developers often need but don't necessarily
know where to find in the sprawling .NET class library. Essentially,
the My objects offer one-stop shopping, with
access to everything from the Windows registry to the current network
connection. Best of all, the My object hierarchy
is organized according to use and is easy to navigate using Visual
Studio IntelliSense.My objects. Out of
these, three core objects centralize functionality from the .NET
Framework and provide computer information. These include:My.Computer
My.ApplicationMy objects provide easy access to various features
that developers often need but don't necessarily
know where to find in the sprawling .NET class library. Essentially,
the My objects offer one-stop shopping, with
access to everything from the Windows registry to the current network
connection. Best of all, the My object hierarchy
is organized according to use and is easy to navigate using Visual
Studio IntelliSense.My objects. Out of
these, three core objects centralize functionality from the .NET
Framework and provide computer information. These include:My.Computer
My.Application
My.User
My.Application
object provides a wealth of information right at your fingertips.
Getting this information is as easy as retrieving a property.My.Application object comes
in handy in a variety of situations. Here are two examples:' Find out what parameters were used to start the application.
Console.Write("Command line parameters: ")
For Each Arg As String In My.Application.CommandLineArgs
Console.Write(Arg & " ")
Next
Console.WriteLine( )
Console.WriteLine( )
' Find out some information about the assembly where this code is located.
' This information comes from metadata (attributes in your code).
Console.WriteLine("Company: " & My.Application.Info.CompanyName)
Console.WriteLine("Description: " & My.Application.Info.Description)
Console.WriteLine("Located in: " & My.Application.Info.DirectoryPath)
Console.WriteLine("Copyright: " & My.Application.Info.Copyright)
Console.WriteLine("Trademark: " & My.Application.Info.Trademark)
Console.WriteLine("Name: " & My.Application.Info.AssemblyName)
Console.WriteLine("Product: " & My.Application.Info.ProductName)
Console.WriteLine("Title: " & My.Application.Info.Title)
Console.WriteLine("Version: " & My.Application.Info.Version.ToString( ))
Console.WriteLine( )PictureBox or ImageList. These
controls insert the picture data into the application resource file
automatically.EmbeddedGraphic (as shown in Figure 2-2).
UserDataFilePath, the type
String, the scope Application
(you'll learn more about this shortly), and the
value CustomerCollection class that accepts only objects
of type Customer when you can build a generic
Collection class that can be configured to accept
objects of any type? On the other hand, performance and type safety
considerations can make a generic solution less desirable. If you use
a generic .NET Collection class to store
Customer objects, for example, how can you be sure
that someone won't accidentally insert another type
of object into the collection, causing an insidious problem later on?System.Collections.ArrayList class.
ArrayList is an
all-purpose, dynamically self-sizing collection. It can hold ordinary
.NET objects or your own custom objects. In order to support this,
ArrayList treats everything as the base
Object type.ArrayList works. For example,
if you want to use ArrayList to store a collection
of Customer objects, you have no way to be sure
that a faulty piece of code won't accidentally
insert strings, integers, or some other type of object, causing
future headaches. For this reason, developers often create their own
strongly typed collection classes—in fact, the .NET class
library is filled with dozens of them.Nothing), is a special flag that indicates no data
is present. Most developers are familiar with null object references,
which indicate that the object has been defined but not created. For
example, in the following code, the FileStream
contains a null reference because it hasn't been
instantiated with the New keyword:Dim fs As FileStream
If fs Is Nothing
' This is always true because the FileStream hasn't
' been created yet.
Console.WriteLine("Object contains a null reference.")
End If0. Boolean variables are False.
String variables are set to an empty string (''") automatically. In
fact, even if you explicitly set a simple data type variable to
Nothing in your code, it will automatically revert
to the empty value (0, False,
or ""), as the following code demonstrates:Dim j As Integer = Nothing
If j = 0 Then
' This is always true because there is an
' implicit conversion between Nothing and 0 for integers.
Console.WriteLine("Non-nullable integer j = " & j)
End If0.
Quite simply, you have no way to know whether this is valid data (the
user placed no orders), or it represents missing information (the
setting couldn't be retrieved or the current user
isn't a registered customer).Public
Shared
Operator, followed by
the symbol for the operator (e.g., +).+) operator:Public Shared Operator+(objA As MyClass, objB as MyClass) As MyClass
' (Code goes here.)
End OperatorObjC = ObjA + ObjB
ObjC = MyClass.Operator+(ObjA, ObjB)
Partial keyword, you
can split a single class into as many pieces as you want. You simply
define the same class in more than one place. Here's
an example that defines a class named SampleClass
in two pieces:Partial Public Class SampleClass
Public Sub MethodA( )
Console.WriteLine("Method A called.")
End Sub
End Class
Partial Public Class SampleClass
Public Sub MethodB( )
Console.WriteLine("Method B called.")
End Sub
End ClassSampleClass
pieces in different source code files in the same project. (The only
restrictions are that you can't define the two
pieces in separate assemblies or in separate namespaces.)SampleClass
and assemble it into a complete, compiled class with two methods,
MethodA( ) and MethodB( ). You
can use both methods, as shown here:Dim Obj As New SampleClass( ) Obj.MethodA( ) Obj.MethodB( )
My objects
aren't defined in a single place. Some come from
classes defined in the
Microsoft.VisualBasic.MyServices namespace, while
others are generated dynamically as you add forms, web services,
configuration settings, and embedded resources to your project.
However, as a developer you can participate in the
My namespace and extend it with your own
ingredients (e.g., useful calculations and tasks that are specific to
your application).My object hierarchy,
simply use a Namespace block with the name
My. For example, you could add this code to create
a new BusinessFunctions class that contains a
company-specific function for generating custom identifiers (by
joining the customer name to a new GUID):Namespace My
Public Class BusinessFunctions
Public Shared Function GenerateNewCustomerID( _
ByVal name As String) As String
Return name & "_" & Guid.NewGuid.ToString( )
End Function
End Class
End NamespaceBusinessFunctions object in the right place, you
can make use of it in your application just like any other
My object. For example, to display a new customer
ID:Console.WriteLine(My.BusinessFunctions.GenerateNewCustomerID("matthew"))My classes you add need to use
shared methods and properties. That's because the
My object won't be instantiated
automatically. As a result, if you use ordinary instance members,
you'll need to create the My
object on your own, and you won't be able to
manipulate it with the same syntax. Another solution is to create a
module in the My namespace, because all the
methods and properties in a module are always shared.My objects
thanks to partial classes. For example, using this feature you could
add new information to the My.Computer object or
new routines to the Return to step out of a function, or
Exit to back out of a loop. However, before VB
2005, there wasn't any way to skip to the next
iteration of a loop.Continue statement is one of those language
details that seems like a minor frill at first, but quickly proves
itself to be a major convenience. The Continue
statement exists in three versions: Continue For,
Continue Do, and Continue
While, each of which is used with a different type of loop
(For ... Next,
Do ... Loop, or
While ... End While).Continue statement works consider
the following code:For i = 1 to 1000
If i Mod 5 = 0 Then
' (Task A code.)
Continue For
End If
' (Task B code.)
Nexti. Whenever i is divisible by
five, the task A code executes. Then, the Continue
For statement is executed, the counter is incremented, and
execution resumes at the beginning of the loop, skipping the code in
task B.For i = 1 to 1000
If i Mod 5 = 0 Then
' (Task A code.)
Else
' (Task B code.)
End If
NextContinue statement, you need to consider a more
complex (and realistic) example.IDisposable
interface, and provide a Dispose( ) method that
you can call to release their resources immediately.Dispose( ) method (or another method
that calls Dispose( ), such as a Close(
) method). VB 2005 provides a new safeguard you can apply
to make sure Dispose( ) is always called: the
Using statement.Using statement in a block structure.
In the first line, when you declare the Using
block, you specify the disposable object you are using. Often,
you'll also create the object at the same time using
the New keyword. Then, you write the code that
uses the disposable object inside the Using block.
Here's an example with a snippet of code that
creates a new file and writes some data to the file:Using NewFile As New System.IO.StreamWriter("c:\MyFile.txt")
NewFile.WriteLine("This is line 1")
NewFile.WriteLine("This is line 2")
End Using
' The file is closed automatically.
' The NewFile object is no longer available here.Using block, the Dispose( )
method is called on the NewFile object, releasing
the file handle.Using block?
Thankfully, .NET makes sure it disposes of the resource no matter how
you exit the Using block, even if an unhandled
exception occurs.Using statement makes sense with all kinds of
disposable objects, such as:FileStream, StreamReader, and
StreamWriter)