.NET for Visual FoxPro Developers

Chapter 4
Introduction to Visual Basic .NET

Many Visual FoxPro developers have an aversion to anything that bears the name “Visual Basic”. This chapter aims to help you look past this prejudice and take a fresh look at the new incarnation of Visual Basic—Visual Basic .NET. As you read this side-by-side comparison of Visual FoxPro and Visual Basic .NET, you’ll see that Visual Basic has grown up and is a first-class citizen alongside C# and C++.

Visual Basic has been around for many years. It was the first language offered by Microsoft that brought Windows programming to the masses. The relationship between Visual FoxPro and Visual Basic communities has often been combative and characterized by religious fervor on both sides of the fence.

One of the biggest bones of contention has been the claim by VB developers that Visual Basic 6 is object-oriented—which most VFP developers argue loudly against! But things have changed. For all intents and purposes, Visual Basic .NET is a new language. Its syntax is similar to Visual Basic, but it was completely rewritten for .NET.

In the next chapter, I’ll cover detailed information on both C# and VB .NET’s object-oriented features. In this chapter, I focus on the syntax of VB .NET compared to VFP. So, hopefully you can put aside any preconceived notions and take a good look at what VB .NET has to offer.

Text Box: ¥

For a side-by-side comparison of Visual Basic .NET, C#, and Visual FoxPro’s operators and keywords, check out “Appendix A – Language Comparison Tables”. For a comparison of each language’s data types, see “Appendix B – Data Type Comparison”.

Changes for Visual Basic 6 backward compatibility

As you learn Visual Basic .NET, you’ll come across a few things that are a little different from the .NET norm. After Visual Studio .NET Beta 1 was released,  Microsoft restored some Visual Basic 6 functionality to VB .NET based on feedback from the Visual Basic community. The changes provide an easier upgrade path from Visual Basic 6 to Visual Basic .NET. These are the three main changes:

·         The value of True – In almost every programming language, when a boolean True is coerced to an integer, its value is one (1). In Visual Basic, it’s always been a minus 1 (-1). Originally, Microsoft was going to change this so VB .NET was in line with other .NET languages, but for backward compatibility reasons VB .NET’s True still evaluates to -1.

·         Behavior of And/Or/Not/XOr – Originally, Microsoft intended to change the And, Or, Not, and XOr operators from bitwise operators (as they were in Visual Basic 6) to logical operators. Based on feedback from the VB community, they left these as bitwise operators and added two new operators instead: AndAlso and OrElse.

·         Declaring Arrays – To bring VB .NET in line with other .NET languages, Microsoft intended to change the way arrays are declared from how it was done in Visual Basic 6. Again, to maintain backward compatibility, they changed it back to the Visual Basic 6 model. Check out the “Arrays” section later in this chapter for details.

Weak Typing vs. Strong Typing

While VB .NET is a strongly typed language, C# is a more strongly typed language. The difference is in C# you must declare all variables and their types before using them. In VB .NET, this is optional.

Option Explicit and Option Strict

VB .NET has two settings that specify how the compiler treats variables—Option Explicit and Option Strict.

The Option Explicit setting specifies whether you can use undeclared variables—not just undeclared variable types, but the variable itself. By default, the Option Explicit setting is “Off”, which allows you to use variables without declaring them. When Option Explicit is “On”, VB .NET acts like C# by forcing you to declare all variables before using them.

Text Box: ¥

Although having the flexibility of being able to turn off variable declaration checking may seem like a “plus”, it’s actually not. You should always turn Option Explicit “On” so the compiler will catch the use of undeclared variables. If Option Explicit is “Off”, the compiler won’t catch variable names with typos resulting in unpredictable behavior at runtime.

Even when Option Strict is “On”, Visual Basic .NET differs a bit from C# when it comes to using variables. In C#, you must initialize a variable’s value before using it. In Visual Basic .NET, you can use a variable without first setting its value (VB .NET sets all variables to a default value when you declare them). Depending on whether you’re an advocate of compiler enforcement or of flexibility you can argue whether this is a good or a bad thing!

The Option Strict setting specifies whether the compiler enforces strict typing. If Option Strict is “Off” (the default), the compiler does not require you to specify a type when you declare a variable. If Option Strict is “On”, then VB .NET acts like C#, forcing you to declare the type of all variables. Option Strict also specifies how much checking the compiler performs when converting between different variable types. If Option Strict is “Off”, no type conversion checking is performed. If Option Strict is “On”, the compiler warns you of any type conversions that may result in a loss of data. For example, if Option Strict is “On” when you copy the value of a Long variable into an Integer variable, the compiler complains because a Long variable can hold values larger than can fit in an Integer. However, if you do the opposite (copy the value of an Integer variable into a Long), the compiler does not complain.

In general, it’s best to set Option Strict “On”. This allows the compiler to catch any conversions that may result in a loss of data, rather than trying to catch them at run time. In addition, explicitly specifying type conversions has speed advantages over allowing them to occur implicitly (automatically). This is because implicit conversions require extra work at runtime to determine the types involved in a conversion.

Assuming that Option Strict and Option Explicit are both “On”, you declare variables by specifying their name followed by their type. For example, the following code declares a data variable named MyDate, a string variable named MyString, and an integer variable named MyInteger:

Dim MyDate As DateTime

Dim MyString As String

Dim MyInteger As Integer

 

You specify the setting of Option Explicit and Option Strict at the application level by means of VS .NET’s Solution Explorer. Just right-click on a project, select Properties from the shortcut menu, and select the Build node under Common Properties in the tree view (Figure 1). You can then set Option Explicit and Option Strict and it will affect all code in your project.

Figure 1. Typically, you should set Option Explicit and Option Strict “On”, so the compiler catches undeclared variables, variable types, and type conversion errors.

It is possible to override these project-level settings by declaring a different setting for Option Explicit or Option Strict at the top of your source files. For example:


Option Explicit Off

Public Class MyForm

    Inherits System.Windows.Forms.Form

End Class

Based on the “best practice” of using strong typing and explicit variable declaration, the rest of the Visual Basic .NET sample code in this book assumes that both of these options are set to “On”.

A simple Visual Basic .NET program

Although this chapter is not about Visual Basic .NET’s object-oriented features, it’s difficult to learn the language syntax without first learning how to create a simple program. Here is a “Hello .NET World” program in VB .NET:

Module MyFirstVBNetProgram

 

    Sub Main()

        Console.WriteLine("Hello .NET World")

    End Sub

 

End Module

There are a few things to note about this program. First of all, every VB .NET program must have a procedure named Main, which is called when the program is first executed. It must return nothing or an integer. If you want to return an integer, you must specify that Main is a Function Procedure instead of a Sub Procedure:

Module MyFirstVBNetProgram

 

    Function Main() As Integer

        Console.WriteLine("Hello .NET World")

        Return 0

    End Function

 

End Module

You can also specify that Main accept a string array parameter. If any command-line parameters are passed when the program is executed, they are placed into this array:

Module MyFirstVBNetProgram

 

  Function Main(ByVal CmdArgs() As String) As Integer

     Console.WriteLine("Hello .NET World")

 

     ' Process any parameters

     If CmdArgs.Length > 0 Then

     ' Build a string containing all parameters

         Dim Parms, Parameter As String

         For Each Parameter In CmdArgs

          Parms += Parameter & " "

         Next

         ' Display the parameters

         Console.WriteLine(Parms)

     End If

 

     Return 0

  End Function

 

End Module

Notice the use of the += operator. In Visual Basic .NET this is a shortcut for:

Text Box: ¥Parms = Parms + Parameter

Although it’s technically accurate for a VB .NET program to have a procedure named Main, in practice, you may not see such a method anywhere in your source code. For example, if you create a new Visual Basic .NET Windows Application using Visual Studio .NET, you won’t find a Main method. What’s happening is behind the scenes the compiler injects a Main method into the IL for you. You can override this behavior and manually create your own Main method.

Visual Basic .NET Syntax

This section provides an overview of VB .NET’s language syntax compared to Visual FoxPro.

Case insensitivity

Visual Basic .NET is like Visual FoxPro in that it is case insensitive. Although the convention in VB .NET is to proper case keywords, you can make them upper case, lower case, or anything in between and the compiler treats them all the same. In C#, keywords are in lower case. If you use upper case or mixed case, the compiler flags it as an error.

To demonstrate case insensitivity, in the following code I have declared a variable, “MyString”, and assigned it a value. In the next line, I reference that variable, but I refer to it as “mystring” (all lowercase). In VB .NET and Visual FoxPro, these two names refer to the same variable:

Dim MyString As String = "Visual Basic .NET is case-insensitive"

Console.WriteLine(mystring)

In contrast, as mentioned in Chapter 3, “Introduction to C#”, C# is case sensitive. If you are the type of developer who tends to mix case freely, this can be a real factor when choosing between Visual Basic .NET and C#. If you tend to be stricter with your casing (and you let IntelliSense “fill in the blanks” for you), it’s not as big of an issue.

End-of-line and line continuation characters

In the area of end-of-line and line continuation characters, Visual Basic .NET is again similar to Visual FoxPro. In VB .NET, a CR+LF indicates the end of a line. If you need to have a statement span multiple lines, you must use the continuation character. In Visual FoxPro, the continuation character is the semicolon (;), but in Visual Basic .NET, it is the underscore
( _ ) character.

Grouping statements together

Visual Basic .NET groups statements together by matching beginning and ending keywords. For example, a class definition begins with the Class keyword and ends with End Class.  A subroutine starts with the keyword Sub and ends with End Sub:

Class MyClass

  Public Sub MySubroutine()

  End Sub

End Class

The use of starting and ending keywords is similar to Visual FoxPro:

DEFINE CLASS MyClass AS Session

 

  PROCEDURE MyProcedure

  ENDPROC

 

  FUNCTION MyFunction

  ENDFUNC

 

ENDDEFINE

Comments

In VB .NET, you use a single quote character to indicate the start of a comment. This is consistent whether the comment is at the beginning of a line or following a statement:

' Here is a comment at the beginning of a line

Dim MyInteger As Integer = 100   ' Here is a comment following a statement

Since statements cannot automatically span lines in Visual Basic .NET without a continuation character, there is no multi-line comment indicators available as in C#.

Namespaces

In Visual Basic .NET, you use the imports keyword to specify where the compiler should look to find classes that are not declared in the current namespace. For example:

Imports System.Data.OleDb

Imports System.Data.SqlClient

Imports System.Data.SqlTypes

All Visual Basic .NET projects automatically import several default namespaces. Since these are imported globally at the project level, you do not need to import these namespaces elsewhere in your project. Different types of projects automatically import different namespaces. To see the default namespaces imported into your project, right-click on your project in the Solution Explorer and select Properties from the shortcut menu. Select the Imports node located under the Common Properties node and you will see a list of default namespaces in the Project Imports list box (Figure 2). Visual Studio .NET allows you to add and remove namespaces from this list.

Figure 2. Visual Basic .NET automatically adds several default namespaces to each project you create. If a namespace appears in this list, you do not need to explicitly declare that you are using the namespace elsewhere.

Visual Basic .NET has another interesting namespace feature—a project root namespace. To see your project’s root namespace, right-click on your project in the Solution Explorer and select Properties from the shortcut menu. Select the General node located under the Common Properties node and you will see your project’s root namespace (Figure 3).

Figure 3. You can specify a root namespace for your project in your project’s Properties dialog.

By default, all classes in your project belong to this root namespace. The root namespace acts as a prefix for all other namespaces declared in the project. For example, if a project’s root namespace is “HW.NetBook”, declaring the “Business” namespace in the following code sample associates the Employee class with the HW.NetBook.Business namespace.

Namespace Business

 

  Public Class Employee

  End Class

 

End Namespace

Defining a simple class

Although I am reserving most of the information about object-orientation in Visual Basic .NET for the next chapter, it’s easier to understand VB .NET’s syntax in the context of a class definition. Here is the simplest class definition in VB .NET:

Class MyFirstVBClass

End Class

Below is the simple class with a single, simple method. Notice I’ve associated the class with the namespace Samples. If the project’s root namespace is HW.NetBook (as it is in this book’s sample code), the fully qualified namespace of this class is HW.NetBook.Samples.

Namespace Samples

 

Public Class MyFirstVBClass

     Public Sub SayHello()

         MessageBox.Show("Hello .NET World!", "Visual Basic .NET")

     End Sub

End Class

 

End Namespace

Unlike the equivalent C# sample code in the previous chapter, you do not need to explicitly import the System.Windows.Forms namespace to use the MessageBox class because, by default, this namespace is imported at the project level.

The default base class

If you do not specify a parent (base) class, it is assumed that a class is derived from the
Object class. As mentioned previously, the Object class is the topmost class in the .NET Framework hierarchy.

Defining class methods

Visual Basic .NET has two different types of methods—subroutines and functions. If your method does not return a value, you must declare it as a subroutine. If it does return a value, you must declare it as a function.

Here is the subroutine declaration syntax:

[Attributes][ProcedureModifier] Sub Identifier [([ FormalParameterList ])]

  ' Method body

End Sub

Here is the function declaration syntax:

[Attributes][ProcedureModifier] Function Identifier [([ FormalParameterList ])]

[ As [Attributes] TypeName]

  ' Method body

End Function

 

Notice that functions have an additional As clause that specifies the return value and its type. As discussed in the “Option Strict and Option Explicit” sections earlier in this chapter, if Option Strict is “On”, you must specify the types of parameters and return values. If it is “Off” and no return type is specified for the function, an Object type is automatically returned.

Returning values from a method

There are two different ways to return a value from a function. You can use the Return statement (which is new in Visual Basic .NET):

Public Function ReturnValue1() As Integer

  Dim intReturnValue As Integer = 1

       Return intReturnValue

End Function

You can also return a value from a method by setting the name of the function to the value to be returned:

Public Function ReturnValue2() As Integer

  Dim intReturnValue As Integer = 2

  ReturnValue2 = intReturnValue

End Function

I recommend using the Return statement to return a value from a Visual Basic .NET method, because it is far more intuitive than setting the name of the function to the value being returned. This makes it easier for others who are perusing your code to figure out what’s going on.

Details regarding the syntax of method declarations are discussed further in Chapter 5, “Object Orientation in C# and Visual Basic .NET”.

Declaring variables

Variables declared within methods are known as local variables (there are no other kind).
They are only visible within the method where they are declared. This is different from
Visual FoxPro, which allows you to declare variables within a method that are local, private, or global.

 

Text Box: ¥Having only local variables at your disposal in both Visual Basic .NET and C# is not restrictive. Good programming practice dictates that you should always declare method variables as local. In Visual FoxPro, rather than using private “mystery” variables, if you want a sub method to see a variable, you should pass it explicitly as a parameter.

To declare a local variable, use the Dim statement followed by the variable name, the As keyword, and the type of the variable:

Dim Count As Integer ' Declare an integer variable named Count

Count = 5            ' Assign Count the value of 5

You can also declare a variable and assign it a value in a single command:

Dim Height As Integer = 6 ' Declare an int variable and assign it a value of 6

If you want to declare multiple variables of the same type in a single statement, simply separate them with commas:

Dim Top, Left As Integer

When you declare multiple values in a single line, you can’t specify default values as you can in C#. However, Visual Basic .NET does allow you to do something you can’t in C#—declare multiple variables of different types in a single line.

Dim Bottom As Integer, FieldName As String

Member variables

As mentioned previously, variables declared at the method level are known as local
variables. However, variables declared at the class level are known as member variables or instance variables:

Public Class MemberAndLocalVariables

 

  Private Test1 As String = "Test1" ' Declare a member variable

 

  Public Sub DeclareVariables()

       Dim Test2 As String = "Test2"     ' Declare a local variable

 

       MessageBox.Show("Displaying " & Test1, 'Member Variable')

       MessageBox.Show("Displaying " & Test2, 'Local Variable')

 

  End Sub

 

End Class

At first, it may seem that member variables are the same as Visual FoxPro properties, but they’re not. In addition to member variables, VB .NET classes can also have properties, which are discussed in Chapter 5, “Object-Orientation in C# and Visual Basic .NET”. For now, just think of member variables as variables declared at the class level that are accessible to all methods in the class.

One other point to note is you can reference member variables the same way you reference local variables. You don’t need a qualifier such as “this” as you do in Visual FoxPro. In the previous example, you could have referenced the Test1 field as “Me.Test1”. The keyword Me in Visual Basic .NET is equivalent to “This” in Visual FoxPro.

Member variable modifiers

There are five different accessibility modifiers you can apply to member variables (Table 1).

Table 1. Field modifiers allow you to specify the visibility of your fields

Modifier

Description

public

Access is not restricted

friend

Access is limited to the current project

protected

Access is limited to the containing class or subclasses

protected  friend

Access is limited to the current project or to subclasses

private

Access is limited to the containing class

 

It’s usually best to specify that a member variable is private. To promote this practice, if you don’t declare an accessibility modifier, Visual Basic .NET considers it private by default. If you want other classes to have access to this field, rather than changing the accessibility modifier, you should create a protected or public property (for details, see the “Properties” section in Chapter 5, “Object-Orientation in C# and Visual Basic .NET”).

Value and reference types

In Chapter 3, “Introduction to C#”, the “Value and reference types” section discussed the difference between value and reference types in the .NET Framework. The distinction between these two different types is the same for all .NET languages—including Visual Basic .NET. Refer to this section in chapter 3 for more details.

The string type

Although the commands used to manipulate a string make it seem like a value type, a string is actually a reference type.

You assign a value to a string variable using a string literal enclosed in double quotes:

Dim Caption As String = ".NET for VFP Developers"

Unlike Visual FoxPro, you can’t use a single quote or square brackets to delimit strings (the single quote is reserved for comments in VB .NET). You concatenate strings in Visual Basic .NET by using either an ampersand (&) or a plus (+) sign (as in VFP):

MessageBox.Show(str1 & " " & str2, "Concatenate with &")

MessageBox.Show(str1 + " " + str2, "Concatenate with +")

Again, the next logical question is, “How do I create a string literal that contains double quotes such as Louis “Satchmo” Armstrong”? You can do this easily by using two double quote marks consecutively:

Dim ManlyMen As String = "Louis ""Satchmo"" Armstrong"

Visual Basic .NET does not recognize any other special character escapes within a string (such as “\n” for a new line in C#). For details, see the “The string type” section in Chapter 3, “Introduction to C#”.

Rather than using character escapes, VB .NET provides enumerated values instead (Table 2). For details, see the “Enumerations” section later in this chapter.

 


Table 2. VB .NET has enumerated values you can concatenate to your strings. This table contains a partial list.

Enumeration

Description

CrLf

Carriage return / linefeed

Cr

Carriage return

Lf

Line feed

NewLine

New line character (same as carriage return / line feed)

Tab

Tab

FormFeed

Form feed

 

If you import the Microsoft.VisualBasic.ControlChars namespace, you can simply use the values specified in the “Enumeration” column of Table 2. For example:

MessageBox.Show("Line 1" + NewLine + "Line 2", "New Line Demo")

Strings as reference types

.NET runtime treats strings a bit differently than other reference types. From a practical perspective, this only becomes an issue when you are concatenating a number of strings together (such as in a loop), because the runtime can proliferate an excess amount of string data on the heap. In situations such as this, you should use the .NET StringBuilder class instead of using Strings.

The StringBuilder class has an Append method you use to concatenate strings together:

Dim StrBuilder As New StringBuilder()

StrBuilder.Append("Texas, ")

StrBuilder.Append("New Mexico, ")

StrBuilder.Append("Colorado")

MessageBox.Show(StrBuilder.ToString(), "StringBuilder")

Enumerations

Visual Basic .NET allows you to define your own complex value types. One of these value types is enumerations and the other is structures (covered in Chapter 5, “Object Orientation in C# and VB .NET”).

Enumerations are a convenience feature of Visual Basic .NET that allows you to group related constants together. For more information on the beauty of enumerations, check out “Enumerations” in Chapter 3, “Introduction to C#”.

Here is an example of declaring an enumeration in Visual Basic .NET:

Public Enum Months As Integer

  January = 1

  February = 2

  March = 3

  April = 4

  May = 5

  June = 6

  July = 7

  August = 8

  September = 9

  October = 10

  November = 11

  December = 12

End Enum

You access an enumeration by referencing its name and specifying the desired member. The compiler converts it to its associated integer value:

Public Class EnumerationTest

  Public Function GetBookPubMonth() As Integer

       ' Access the enumeration

       Dim PubMonth As Months = Months.September

  Return PubMonth

  End Function

End Class

Although an incrementing integer is the most common form of an enumeration, your enumeration constant values can be any integer value, including negative numbers, and in any order. For example, the following enumeration lists three people’s last names in alphabetical order, causing their windsurfing ability rating to appear in non-sequential order:

Public Enum WindSurfingAbility As Integer

  Egger = 9

  Fabulous_Ferguson = 8

  McNeish = -3

  Strahl = 10

End Enum

Although enumerations are Integer types by default, you can specify that they are Byte, Integer, Long, or Short. For example:

Public Enum HairLength As Long

As Long specifies that the HairLength class is derived from the type “Long”. For details on subclassing and inheritance, see Chapter 5, “Object Orientation in C# and Visual Basic .NET.

Arrays

All arrays in VB .NET are zero-based, meaning the first element of the array is zero (0), rather than one (1) as in Visual FoxPro. In addition, all arrays must contain values of the same type. You can’t mix and match integers, strings, dates, and so on in a single array.

Declaring Arrays

In Visual Basic .NET, arrays are declared the same way as other variables, except you add parentheses after the array name:

Dim KidsAges() As Integer

You can also declare an array and size it in one step:

Dim KidsNames(2) As String

If you compare this line of VB .NET code to the same C# code, you’ll notice a difference in the declared size of the array. In C#, I would set the size of the array to three (3) elements. Here, it looks like I’ve sized the array to only contain only two—however, this is not the case. In order to maintain backward compatibility with Visual Basic 6, the way you declare arrays in Visual Basic .NET is slightly different from other .NET languages.

When you declare the size of an array in VB .NET, you declare the upper limit of the array rather than the total number of elements. For example, in the KidsNames array declared here, I want a total number of three elements. Since arrays are zero-based, the first element is zero, the second element is one, and the last element is two. In VB .NET, I use this upper element value to specify the size of the array.

Although this is non-standard, this concession was made by Microsoft’s VB .NET engineers to allow backward compatibility with Visual Basic 6.

Redimensioning arrays

Unlike C#, you can change the size of any array dimension by using VB .NET’s ReDim statement. The following code shows how to dimension and redimension an array:

Dim ScaryAnimals() As String = {"Lions", "Tigers"}

ReDim Preserve ScaryAnimals(2)

The first line of this code dimensions the array size to two implicitly, since I have specified two string elements (Lions and Tigers). The second line redimensions the array to hold three elements (remember, VB .NET’s idiosyncrasy—you specify the highest element number rather than the total number of elements). Notice the use of the keyword Preserve. If you do not add this keyword, VB .NET clears out the other array elements when it redimensions the array. Note that ReDim can only be used on an existing array—you can’t initialize a new array by using ReDim. Also, you can only change the size of an array dimension using ReDim; you can’t change the number of dimensions.

Storing values to arrays

You set initial values of array elements when you declare an array:

Dim KidsMiddleNames() As String = {"Christopher", "Mark", "James"}

Or, you can store values in the array elements after declaring the array:

Dim KidsNames(2) As String

KidsNames(0) = "Jordan"

KidsNames(1) = "Timothy"

KidsNames(2) = "Alexander"


Sorting arrays

You easily sort the elements of an array by calling the Array class’ Sort method:

Array.Sort(KidsNames)

You reverse the sort order by calling the Array class’ Reverse method:

Array.Reverse(KidsNames)

Multidimensional arrays

In Visual FoxPro, you can create one and two-dimensional arrays. Visual Basic .NET allows you to create multidimensional arrays—arrays with three or more dimensions.

Multidimensional arrays are either rectangular (every row has the same number of columns) or jagged (each row can have a different number of columns).

Defining multidimensional rectangular arrays

In VB .NET, you declare a multidimensional, rectangular array by adding one or more commas within the parentheses of the array declaration. Each comma you add specifies an additional array dimension. Here is the definition of a two-dimensional, rectangular array:

Dim ArrayKids(,) As String = {{"Jordan", "McNeish"}, _

              {"Timothy", "McNeish"}, _

              {"Alexander", "McNeish"}}

Defining jagged arrays

A jagged array is an “array of arrays”. They are also multidimensional arrays, but each row can have a different number of columns. You define a jagged array by adding an extra set of parentheses for each dimension. In the following example, the jagged array has three elements in its first dimension. Its second dimension has a different size for each row. The first row has three columns, the second row has two columns, and the third row has one column:

Dim Musicians()() As String = {New String() {"Stevie", "Ray", "Vaughn"}, _

    New String() {"Jimi", "Hendrix"}, _

    New String() {"Bono"}}

 

' Show all three names of the first musician

MessageBox.Show(Musicians(0)(0) + " " & _

Musicians(0)(1) & " " & _

Musicians(0)(2), "Jagged Arrays")

Type conversions

When working with strongly typed languages, converting between different data types is an important consideration. VB .NET provides both implicit and explicit type conversion.

 

Text Box: ¥For a list of VB .NET data types and a comparison between VB .NET, C#, and VFP data types, check out “Appendix C – Data Type Comparison”.

Implicit type conversions

Visual Basic .NET implicitly converts some values from one type to another. In the following example, VB .NET converts a short value to an integer and then to a double:

Dim x As Short = 10

Dim y As Integer = x

Dim z As Double = y

Table 3 lists the types that Visual Basic .NET can implicitly (automatically) convert.

Table 3. Types that Visual Basic .NET can implicitly convert.

From Type

To Type

byte

ushort, short, uint, int, ulong, long, float, double, decimal

sbyte

short, int, long, float, double, decimal

short

int, long, float, double, decimal

ushort

uint, int, ulong, long, float, double, decimal

char

ushort, uint, int, ulong, long, float, double, decimal

int

long, float, double, decimal

uint

long, ulong, float, double, decimal

long

float, double, decimal

ulong

float, double, decimal

float

double

Explicit type conversion

If the compiler refuses to implicitly convert a value from one type to another, you can explicitly convert it yourself. Visual Basic .NET provides a number of ways to do this.

The first method is to use Visual Basic .NET’s conversion keywords (Table 4).

Table 4. Visual Basic .NET provides conversions keywords you can use to explicitly convert values from one type to another.

Keyword

Description

CBool

Converts any numeric type, String, Object to Boolean

CByte

Converts any numeric type, any enumerated type, Boolean, String, Object to Byte

CChar

Converts String, Object to Char

CDate

Converts String, Object to Date

CDbl

Converts Any numeric type, Boolean, String, Object to Double

CDec

Converts any numeric type, Boolean, String, Object to Decimal

CInt

Converts any numeric type, Boolean, String, Object to Integer

CLng

Converts any numeric type, Boolean String, Object to Long

CObj

Converts any type to Object

CShort

Converts any numeric type, Boolean, String, Object to Short

CSng

Converts any numeric type, Boolean, String, Object to Single

CStr

Converts any numeric type, Boolean, Char, Char() array, Date, Object to String

For example, to convert an Integer to Byte you use the CByte keyword:

Dim x As Integer = 20

Dim y As Byte = CByte(x)

You can also use the System.Convert class to perform conversions instead. The Convert class has a number of different conversion methods to use for converting values (Table 5). For example, to perform the same conversion in the previous example using the Convert class, you do it this way:

Dim x As Integer = 20

Dim y As Byte = Convert.ToByte(x)

Text Box: ¥

You will experience better performance using the System.Convert class rather than the conversion functions. This is because the Convert class has overloaded methods specifically designed to convert each different type. However, the type conversion functions such as CStr and CDate take into consideration the locale settings of your system, so if this functionality is important to you, it may be worth the performance hit.

Table 5. The Convert class contains a number of methods to use for converting values from one type to another. This is a partial list.

Keyword

Description

ToBoolean

Converts a value to Boolean

ToByte

Converts a value to an 8-bit unsigned integer

ToChar

Converts a value to a Unicode character

ToDateTime

Converts a value to DateTime

ToDecimal

Converts a value to Decimal

ToDouble

Converts a value to Double

ToInt16

Converts a value to a 16-bit signed Integer

ToInt32

Converts a value to a 32-bit signed Integer

ToInt64

Converts a value to a 64-bit signed integer

ToSByte

Converts a value to an 8-bit signed integer

ToSingle

Converts a value to a single-precision floating point number

ToUInt16

Converts a value to a 16-bit unsigned integer

ToUInt32

Converts a value to a 32-bit unsigned integer

ToUInt64

Converts a value to a 64-bit unsigned integer

 

The CType function

The conversion keywords and System.Convert class discussed in the previous section are great for converting basic value types, but you need something else if you want to convert more complex objects. That something else is the CType function.

CType is a Visual Basic .NET function that allows you to convert an expression to a data type, an object, structure, class, or interface. The CType function accepts two parameters. The first parameter is an expression to be converted. Often this first parameter contains an object reference. The second parameter is the destination type you want the expression converted to. For example, the following code converts an integer to decimal:

Dim x As Integer = 100

Dim y As Decimal = CType(x, Decimal)

Converting to string

If you need to convert a value to a string, the Object class has a ToString method that is inherited by all classes in the .NET Framework. This method returns the string representation of the object. So, for example, do the following to get a string representation of an integer:

Dim i As Integer = 10

Dim s As String = i.ToString()

Converting strings with Val

If you need to convert strings to value types, you can use one of the conversion keywords listed in the “Explicit type conversion” section earlier in this chapter. In addition, you can use the Val function, which is a little more forgiving when it comes to converting strings to numeric values—it lets you convert strings that contain both numeric and character values.

Val() stops converting a string when it hits a character that it can’t recognize as part of a number. In the following example, the string containing the value “567 Test” is converted by the Val() function. The resulting value is 567:

Dim i As Double

Dim z As String = "567 Test"

i = Val(z)    ' Returns 567

Boxing and unboxing in Visual Basic .NET

As described previously, boxing is the process of converting a value type to a reference type. Unboxing is the process of converting the value of a reference type back to a value type.

For example, Boxing occurs implicitly when you store an integer into an object:

Dim x As Integer

Dim y As Object = x

For a diagram showing what happens in memory when a value is boxed, check out “Boxing and unboxing values” in Chapter 3, “Introduction to C#”.

In Visual Basic .NET, you cannot explicitly unbox values the same way as you can in C#.

 

Text Box: ¥Because Visual Basic .NET cannot explicitly unbox values, it relies on the helper functions found in the Microsoft.VisualBasic.Helpers namespace, which are far less efficient than C#’s explicit unboxing.

The TypeOf operator

You can determine if an object is of a particular type by using the TypeOf operator. This is useful in situations where a method receives a generic Object parameter and wants to determine its specific type. For example, the following method receives a parameter of type Object. It then checks if it is of the type MyClass1:

Public Class TypeOfOperatorDemo

    Public Sub CheckClass(ByVal TestObject As Object)

       If TypeOf TestObject Is MyClass1 Then

          MessageBox.Show("TestObject is MyClass1", "TypeOf operator")

       Else

          MessageBox.Show("TestObject is not MyClass1", "TypeOf operator")

       End If

    End Sub

End Class

If statement

Visual Basic .NET’s If statement is similar to Visual FoxPro’s IF..ENDIF statement. If the expression being evaluated is true, the code following Then is executed. Optionally, you can add an Else statement to the If that gets executed if the condition expression evaluates to False. You can also nest If statements.

Dim HavingFun As Boolean = True

If HavingFun Then

  MessageBox.Show("We are having fun!", "if demo")

Else

  MessageBox.Show("We are NOT having fun!", "if demo")

End If

If you want to test an additional condition in the Else, use ElseIf:

Dim MyInteger As Integer = 99

If MyInteger < 10 Then

  MessageBox.Show("MyInteger is less than 10", "If...End If")

ElseIf MyInteger < 100 Then

  MessageBox.Show("MyInteger is more than 9, but less than 100", "If...End If")

End If


Select…Case statement

The Visual Basic .NET Select…Case statement is equivalent to Visual FoxPro’s
DO CASE statement. Based on the value of the expression, one of the case statements is selected for execution. You can specify a Case Else, which is the same as VFP’s OTHERWISE clause. If the switch expression does not match any of the cases, control is passed to the Case Else. If no Case Else is present, control passes to the first command following the End Select.

Dim TestValue As Integer = 3

Select Case TestValue

  Case 1

       MessageBox.Show("TestValue = 1", "Select...Case")

  Case 2

       MessageBox.Show("TestValue = 2", "Select...Case")

  Case 3, 4

       MessageBox.Show("TestValue = 3 or 4", "Select...Case")

  Case Else

       MessageBox.Show("TestValue is not 1, 2, 3, or 4", "Select...Case")

End Select

Unlike C#, you don’t have to add a break statement at the end of each case, which is a nice feature!

For…Next loop

Visual Basic .NET’s For…Next loops are equivalent to Visual FoxPro’s FOR…ENDFOR command. It iterates through a loop while a particular condition is true.

In the For…Next loop, the loop executes for as long as the counter variable is between the specified values. The Next statement is typically used to increment or decrement the counter value.

Dim i As Integer

Dim Message As String

 

For i = 0 To 3

  Message += "Message " + i.ToString() + NewLine

Next i

You exit out of a For…Next loop at any point by using the Exit For statement.

While loop

The While loop is equivalent to Visual FoxPro’s DO…WHILE loop. It is a pre-test loop meaning that if the condition evaluates to false, the loop is not executed at all. While loops are often used to repeat a block of code for an undetermined number of times.

Public Sub WhileLoopDemo()

    Dim Condition As Boolean = True

    While Condition

        Dim i As Integer = 1

        MessageBox.Show("While loop count " + i.ToString(), _

          "While loop")

        i += 1

        Condition = False

    End While

End Sub

You exit out of a While loop at any point by using the Exit While statement.

Do loop

The Visual Basic .NET Do loop repeats a block of statements while a condition is true or until a condition becomes true. If you use the Do While construct, the loop executes while a condition is true. If you use the Do Until construct, the loop executes until the condition becomes true.

The While and Until keywords can be used at either the top or bottom of the loop. If they are used at the top of the loop, the condition is checked before the loop is executed. If they are placed at the bottom of the loop as shown in the following example, the condition is checked after the loop executes. This means the loop always executes at least once. This is different than Visual FoxPro’s DO WHILE loop, which only evaluates the condition at the top of the loop.

Dim Condition As Boolean = False

Do

  Dim i As Integer = 1

  MessageBox.Show("Do While loop count " + i.ToString(), _

   "Do...While loop")

i += 1

Loop While Condition

You exit out of a Do loop at any point by using the Exit Do statement.

For Each loop

The Visual Basic .NET For Each loop executes a group of statements for each element in an array or item in a collection. It is equivalent to Visual FoxPro’s FOR EACH command.

Dim VersionList, Version As String

Dim VSNetVersions() As String = {"Standard", "Professional", _

  "Enterprise Developer", _

  "Enterprise Architect"}

For Each Version In VSNetVersions

  VersionList += "VS .NET " + Version + NewLine

Next

MessageBox.Show(VersionList, "ForEach loop")

You exit out of a For Each loop at any point by using the Exit For statement.


With statement

Visual Basic .NET’s With statement is equivalent to Visual FoxPro’s WITH…ENDWITH command. You specify an object reference at the top of the With statement, then refer to properties and methods of the object within the statement by specifying the name of the object. Any expression starting with a period in the With statement is evaluated as if it is prefixed by the object name. For example:

Dim ReturnDemo As New ReturnValuesDemo()

Dim ReturnValue As Integer

With ReturnDemo

  ReturnValue = .ReturnValue1()

  ReturnValue = .ReturnValue2()

End With

XML Documentation Tool

Although XML documentation was not built into Visual Studio .NET for VB .NET, several months after the release of VS .NET, a stand-alone tool was released by Microsoft that allows you to create XML documentation for VB .NET projects. To get this tool, download it from the VB .NET “GotDotNet” Web site: http://www.gotdotnet.com/team/vb.

This tool works a bit differently than the Visual Studio .NET XML documentation tool for C#. With C# XML documentation, you enter your XML comments directly in your code. These comments are compiled into the assembly and can be viewed in an Object Browser and with IntelliSense. In addition VS .NET automatically builds XML Comment Web pages for you from these XML comments (see Chapter 3, “Introduction to C#” for details).

With the VB .NET XML Documentation Tool, your XML comments are not stored in the source code, but in a separate XML file. Like C#, these XML comments can also be viewed in an Object Browser and with IntelliSense. However, there is no facility to create Comment Web pages from these VB .NET XML comments. In addition, since the comments are not stored in the source code this means that:

1.       Either, you don’t put any comments in your source code (not recommended).

2.       Or, you duplicate your comments—one copy in your source code and one in the XML file.

I see this as a serious limitation of this tool. You really should place comments in your source code for your benefit and the benefit of developers who have to examine your code.

After downloading the VB .NET XML Documentation Tool, you run it by double-clicking the “XML Documentation Tool.exe” file. This launches the XML Documentation Tool dialog (Figure 4).

Figure 4. The XML Documentation Tool for Visual Basic .NET allows you to create XML comments for developers who do not have access to your source code.

Check out the associated ReadMe.htm file for information on how to use this tool to create XML comments for your VB .NET code.

Conclusion

Visual Basic .NET has come a long way from Visual Basic 6 and is now a powerful, fully object-oriented language. It’s as different as FoxPro 2.6 and Visual FoxPro (and then some). Of all the .NET languages, its syntax is most similar to Visual FoxPro and, as you would expect from Visual Basic, there are a number of convenience features that make it worth looking at as your programming language of choice. Since Microsoft has always stressed Visual Basic’s ease of use, you can expect this emphasis to translate into even more convenience features in the future.

 


.NET for Visual FoxPro Developers