Visual Basic.NET

< BACK  NEXT >
[oR]

Visual Basic is by a large margin the most popular programming language in the Windows world. Visual Basic.NET (VB.NET) brings enormous changes to this widely used tool. Like C#, VB.NET is built on the Common Language Runtime, and so large parts of the language are effectively defined by the CLR. In fact, except for their syntax, C# and VB.NET are largely the same language. Because both owe so much to the CLR and the .NET Framework class library, the functionality of the two is very similar.

VB.NET can be compiled using Visual Studio.NET or vbc.exe, a command-line compiler supplied with the .NET Framework. Unlike C#, however, Microsoft has not submitted VB.NET to a standards body. Accordingly, while the open source world or some other third party could still create a clone, the Microsoft tools are likely to be the only viable choices for working in this language, at least for now.

Only Microsoft provides VB.NET compilers today

A VB.NET Example

The quickest way to get a feeling for VB.NET is to see a simple example. The example that follows implements the same functionality as did the C# example shown earlier in this chapter. As you'll see, the differences from that example are largely cosmetic.

 ' A VB.NET example Module DisplayValues     Interface IMath         Function Factorial(ByVal F As Integer) _             As Integer         Function SquareRoot(ByVal S As Double) _             As Double     End Interface     Class Compute         Implements IMath         Function Factorial(ByVal F As Integer) _             As Integer Implements IMath.Factorial             Dim I As Integer             Dim Result As Integer = 1             For I = 2 To F                 Result = Result * I             Next             Return Result         End Function         Function SquareRoot(ByVal S As Double) _             As Double Implements IMath.SquareRoot             Return System.Math.Sqrt(S)         End Function     End Class     Sub Main()         Dim C As Compute = New Compute()         Dim V As Integer         V = 5         System.Console.WriteLine( _             "{0}  factorial: {1}", _             V, C.Factorial(V))         System.Console.WriteLine( _             "Square root of {0} : {1:f4} ", _             V, C.SquareRoot(V))     End Sub End Module 

The example begins with a simple comment, indicated by the single quote that begins the line. Following the comment is an instance of the Module type that contains all of the code in this example. Module is a reference type, but it's not legal to create an instance of this type. Instead, its primary purpose is to provide a container for a group of VB.NET classes, interfaces, and other types. In this case, the module contains an interface, a class, and a Sub Main procedure. It's also legal for a module to contain directly method definitions, variable declarations, and more that can be used throughout the module.

A Module provides a container for other VB.NET types

C# or VB.NET?

Before .NET, the language choxice facing Microsoft-oriented developers was simple. If you were a hard-core developer, deeply proud of your technical knowledge, you embraced C++ in all its thorny glory. Alternatively, if you were more interested in getting the job done than in fancy technology and if that job wasn't too terribly complex or low level, you chose Visual Basic 6. Sure, the C++ guys abused you for your lack of linguistic savoir faire, but your code had a lot fewer obscure bugs.

This decade-old divide is over. C# and VB.NET are very nearly the same language. Except for relatively uncommon things such as writing unsafe code and operator overloading, they're equally powerful. Microsoft may change this in the future, making the feature sets of the two languages diverge. Until this happens, however (if it ever does), the main issue in making the choice is personal preference, which is really another way of saying syntax.

Developers get very attached to how their language looks. C-oriented people love curly braces, while VB developers feel at home with Dim statements. Since many more developers use Visual Basic today than C++, I expect that VB.NET will be a more popular choice than C#. For the vast majority of VB developers who are fond of VB-style syntax, there's no reason to switch to C#. Even the .NET Framework documentation supplied by Microsoft is quite even-handed, usually providing examples in both languages. Given its much greater popularity today, I expect the dominant language for building Windows applications five years from now will still be Visual Basic.

In spite of this, however, I believe that any developer who knows C# can (and should) acquire at least a reading knowledge of VB.NET, and vice versa. The core semantics are identical, and after all, this is the really hard part of learning a language. In fact, to illustrate the near equality of these two languages, the examples in the following chapters of this book alternate more or less randomly between the two. In the world of .NET, you shouldn't think of yourself as a VB.NET developer or a C# developer. Whichever language you choose, you will in fact be a .NET Framework developer.

The module's interface is named IMath, and as in the earlier C# example, it defines the methods (or in the argot of Visual Basic, the functions) Factorial and SquareRoot. Each takes a single parameter, and each is defined to be passed by value, which means a copy of the parameter is made within the function. (The trailing underscore is the line continuation character, indicating that the following line should be treated as though no line break were present.) Passing by value is the default, so the example would work just the same without the ByVal indications. Passing by reference is the default in Visual Basic 6, which shows one example of how the language was changed to match the underlying semantics of the CLR.

By default, VB.NET passes parameters by value, unlike Visual Basic 6

The class Compute, which is the VB.NET expression of a CTS class, implements the IMath interface. Each of the functions in this class must explicitly identity the interface method it implements. Apart from this, the functions are just as in the earlier C# example except that a Visual Basic style syntax is used. Note particularly that the call to System.Math.Sqrt is identical to its form in the C# example. C#, VB.NET, and any other language built on the CLR can access services in the .NET Framework class library in much the same way.

A VB.NET class is an expression of a CTS class

This simple example ends with a Sub Main procedure, which is analogous to C#'s Main method. The application begins executing here. In this example, Sub Main creates an instance of the Compute class using the VB.NET New operator (which will eventually be translated into the MSIL instruction newobj). It then declares an Integer variable and sets its value to 5.

Execution begins in the Sub Main procedure

As in the C# example, this simple program's results are written out using the WriteLine method of the Console class. Because this method is part of the .NET Framework class library rather than any particular language, it looks exactly the same here as it did in the C# example. Not too surprisingly, then, the output of this simple program is

 5 factorial: 120 Square root of 5: 2.2361 

just as before.

To someone who knows Visual Basic 6, VB.NET will look familiar. To someone who knows C#, VB.NET will act in a broadly familiar way since it's built on the same foundation. But VB.NET is not the same as either Visual Basic 6 or C#. The similarities can be very helpful in learning this new language, but they can also be misleading. Be careful.

VB.NET's similarities to Visual Basic 6 both help and hurt in learning this new language

VB.NET Types

Like C#, the types defined by VB.NET are built on the CTS types provided by the CLR. Table 4-2 shows most of these types and their VB.NET equivalents.

Notice that some types, such as unsigned integers, are missing from VB.NET. Unsigned integers are a familiar concept to C++ developers but not to typical Visual Basic 6 developers. The core CTS types defined in the System namespace are available in VB.NET just as in C#, however, so a VB.NET developer is free to declare an unsigned integer using

VB.NET doesn't support all of the CTS types

 Dim J As System.UInt32 

Unlike C#, VB.NET is not case sensitive. There are some fairly strong conventions, however, which are illustrated in the example shown earlier. For people coming to .NET from Visual Basic 6, this case insensitivity will seem entirely normal. It's one example of why both VB.NET and C# exist, since the more a new environment has in common with the old one, the more likely people will adopt it.

Table 4-2. Some CTS Types and Their VB.NET Equivalents
CTS VB.NET
Byte Byte
Char Char
Int16 Short
Int32 Integer
Int64 Long
Single Single
Double Double
Decimal Decimal
Boolean Boolean
Structure Structure
String String
Class Class
Interface Interface
Delegate Delegate

Classes

VB.NET classes expose the behaviors of a CTS class using a VB-style syntax. Accordingly, VB.NET classes can implement one or more interfaces, but they can inherit from at most one other class. In VB.NET, a class Calculator that implements the interfaces IAlgebra and ITrig and inherits from the class MathBasics looks like this:

Like a CTS class, a VB.NET class can inherit directly from only one other class

 Class Calculator     Inherits MathBasics     Implements IAlgebra     Implements ITrig . . . End Class 

Note that, as in C#, the base class must precede the interfaces. Note also that any class this one inherits from might be written in VB.NET or in C# or perhaps in some other CLR-based language. As long as the language follows the rules laid down in the CLR's Common Language Specification, cross-language inheritance is straightforward. Also, if the class inherits from another class, it can potentially override one or more of the type members, such as a method, in its parent. This is allowed only if the member being overridden is declared with the keyword Overridable, analogous to C#'s keyword virtual.

VB.NET classes can be labeled as NotInheritable or MustInherit, which means the same thing as sealed and abstract, respectively, the terms used by the CTS and C#. VB.NET classes can also be assigned various accessibilities, such as Public and Friend, which largely map to visibilities defined by the CTS. A VB.NET class can contain variables, methods, properties, events, and more, just as defined by the CTS. Each of these can have an access modifier specified, such as Public, Private, or Friend. A class can also contain one or more constructors that get called whenever an instance of this class is created. Unlike C#, however, VB.NET does not support operator overloading. A class can't redefine what various standard operators mean when used with an instance of this class.

VB.NET doesn't support operator overloading

Interfaces

Interfaces as defined by the CTS are a fairly simple concept. VB.NET essentially just provides a VB-derived syntax for expressing what the CTS specifies. Along with the interface behavior shown earlier, CTS interfaces can inherit from one or more other interfaces. In VB.NET, for example, defining an interface ITrig that inherits from the three interfaces, ISine, ICosine, and ITangent, would look like this:

Like a CTS interface, a VB.NET interface can inherit directly from one or more other interfaces

 Interface ITrig     Inherits ISine     Inherits ICosine     Inherits ITangent ... End Interface 

Is Inheritance Really Worthwhile?

Inheritance is an essential part of object technology. Until .NET, Visual Basic didn't really support inheritance, and so (quite correctly) it was not viewed as an object-oriented language. VB.NET has inheritance, since it's built on the CLR, and so it is unquestionably truly object-oriented.

But is this a good thing? Microsoft certainly could have added inheritance to Visual Basic long ago, yet the language's keepers chose not to. Whenever I asked Microsoft why this was so, the answers revolved around two main points. First, inheritance can be tricky to understand and to get right. In a class hierarchy many levels deep, with some methods overridden and others overloaded, figuring out exactly what's going on isn't always easy. Given that the primary target audience for Visual Basic was not developers with formal backgrounds in computer science, it made sense to keep it simple.

The second point often made about why Visual Basic didn't have inheritance was that in many contexts, inheritance was not a good thing. This argument was made most strongly with COM, a technology that has no direct support for implementation inheritance. Inheritance binds a child class to its parent very closely, which means that a change in the parent can be catastrophic for the child. This fragile base class issue is especially problematic when the parent and child classes are written and maintained by completely separate organizations or when the parent's source isn't available to the creator of the child. In the component-oriented world of COM, this is a more than plausible argument.

So why has Microsoft apparently changed its mind about inheritance? Inheritance still can be problematic if changes in a parent class aren't communicated effectively to all developers who depend on that class, and it can also be complicated. The arguments Microsoft made are not incorrect. Yet the triumph of object technology is complete: Objects are everywhere. To create new languages in a completely new environment that is, to create the .NET Framework without full support for inheritance would brand any organization as irretrievably retro. And the benefits of inheritance, especially those gained by providing a large set of reusable classes such as the .NET Framework class library, are huge. The pendulum has swung, and inheritance is now essential.

Besides, most of the people in Redmond who argued against inheritance in the 1990s have probably retired by now. Never underestimate the power of new blood in a development group.

Structures

Because both are based on the structure type defined by the CTS, structures in VB.NET are very much like structures in C#. Like a class, a structure can contain fields, members, and properties, implement interfaces, and more. VB.NET structures are value types, of course, which means that they can neither inherit from nor be inherited by another type. A simple employee structure might be defined in VB.NET as follows:

VB.NET structures can contain fields, provide methods, and more

 Structure Employee     Public Name As String     Public Age As Integer End Structure 

To keep the example simple, this structure contains only data members. As described earlier, however, CTS structures and thus VB.NET structures are in fact nearly as powerful as classes.

Delegates

The idea of passing an explicit reference to a procedure or function and then calling that procedure or function is not something that the typical Visual Basic programmer is accustomed to. Yet the CLR provides support for delegates, which allows exactly this. Why not make this support visible in VB.NET?

VB.NET's creators chose to do this, allowing VB.NET programmers to create callbacks and other event-oriented code easily. Here's an example, the same one shown earlier in C#, of creating and using a delegate in VB.NET:

VB.NET allows creating and using delegates

 Module Module1     Delegate Sub SDelegate(ByVal S As String)     Sub CallDelegate(ByVal Write As SDelegate)         System.Console.WriteLine("In CallDelegate")         Write("A delegated hello")     End Sub     Sub WriteString(ByVal S As String)         System.Console.WriteLine( _             "In WriteString: {0}", S)     End Sub     Sub Main()         Dim Del As New SDelegate( _             AddressOf WriteString)         CallDelegate(Del)     End Sub End Module 

Although it's written in VB.NET, this code functions exactly like the C# example shown earlier in this chapter. Like that example, this one begins by defining SDelegate as a delegate type. As before, SDelegate objects can contain references only to methods that take a single String parameter. In the example's Sub Main method, a variable Del of type SDelegate is declared and then initialized to contain a reference to the WriteString subroutine. (A VB.NET subroutine is a method that, unlike a function, returns no result.) Doing this requires using VB.NET's AddressOf keyword before the subroutine's name. Sub Main then invokes CallDelegate, passing in Del as a parameter.

CallDelegate has an SDelegate parameter named Write. When Write is called, the method in the delegate that was passed into CallDelegate is actually invoked. In this example, that method is WriteString, so the code inside the WriteString procedure executes next. The output of this simple example is exactly the same as for the C# version shown earlier in this chapter:

 In CallDelegate In WriteString: A delegated hello 

Is VB.NET Too Hard?

Maybe. There have been lots of complaints about the changes, and certainly some Visual Basic 6 developers will get left behind. Microsoft has historically targeted quite separate developer markets with Visual Basic and C++, yet with the .NET Framework, this distinction is greatly blurred. VB.NET and C# are functionally almost identical.

The .NET Framework is certainly simpler in many ways than the Windows DNA environment. The complexity of COM for cross-language calls is no longer required, for example. But the Framework is also harder for a certain class of developers, especially those with no formal training in computer science. One reason for Microsoft's success in the developer market was the approachability of Visual Basic. The people who create software tools often forget that they're almost always much better software developers than the people who will use those tools. As a result, they tend to create tools that they themselves would like to use, tools that are too complex for many of their potential customers.

The creators of Visual Basic never made this mistake. Despite the opprobrium heaped on the language and its users by C++ developers, Microsoft kept a clear focus on the developer population and skill level they wished to target. This was a good decision, as Visual Basic is now perhaps the world's most widely used programming language.

And yet many Visual Basic developers wanted more. VB.NET certainly gives them more, but it also requires all Visual Basic developers to step up a level in their technical knowledge. The skills required to build the GUI-based client of a two-tier application, the original target for this language, are almost entirely unrelated to what's needed to build today's scalable, multitier, Web-accessible solutions. Given this, perhaps the original audience Microsoft targeted for Visual Basic, some of the audience was just a step above power users, no longer has a role. With its complete object orientation and large set of more advanced features, VB.NET will certainly be too complex for many of them.

Yet building today's applications effectively was becoming more and more difficult with the old Visual Basic. Between a rock and a hard place, Microsoft chose to make this popular language both more powerful and more complex. Some developers will be very happy about this, but some won't. You can't please everybody, and the market will decide whether Microsoft has made the right decision.

Delegates are another example of the additional features Visual Basic has acquired from being rebuilt on the CLR. While this rethinking of the language certainly requires lots of learning from developers using it, the reward is a substantial set of features.

Arrays

Like arrays in C# and other CLR-based languages, arrays in VB.NET are reference types that inherit from the standard System.Array class. Accordingly, all of the methods and properties that class makes available are also usable with any VB.NET array. Arrays in VB.NET look much like arrays in earlier versions of Visual Basic. Perhaps the biggest difference is that the first member of a VB.NET array is referenced as element zero, while in previous versions of this language, the first member was element one. The number of elements in an array is thus one greater than the number that appears in its declaration. For example, the following statement declares an array of eleven integers:

Unlike Visual Basic 6, array indexes in VB.NET start at zero

 Dim Ages(10) As Integer 

Unlike C#, there's no need to create explicitly an instance of the array using New. It's also possible to declare an array with no explicit size and later use the ReDim statement to specify how big it will be. For example, this code

 Dim Ages() As Integer ReDim Ages(10) 

results in an array of eleven integers just as in the previous example. Note that the index for both of these arrays goes from 0 to 10, not 1 to 10.

VB.NET also allows multidimensional arrays. For example, the statement

 Dim Points(10,20) As Integer 

creates a two-dimensional array of integers with 11 and 21 elements, respectively. Once again, both dimensions are zero-based, which means that the indexes go from 0 to 10 in the array's first dimension and 0 to 20 in the second dimension.

VB.NET Control Structures

While the CLR says a lot about what a .NET Framework based language's types should look like, it says essentially nothing about how that language's control structures should look. Accordingly, adapting Visual Basic to the CLR required making changes to VB's types, but the language's control structures are fairly standard. An If statement, for example, looks like this:

VB.NET's control structures will look familiar to most developers

 If (X > Y) Then     P = True Else     P = False End If 

while a Select Case statement analogous to the C# switch shown earlier looks like this:

 Select Case X     Case 1         Y = 100     Case 2         Y = 200     Case Else         Y = 300 End Select 

As in the C# example, different values of x will cause y to be set to 100, 200, or 300. Although it's not shown here, the Case clauses can also specify a range rather than a single value.

The loop statements available in VB.NET include a While loop, which ends when a specified Boolean condition is no longer true; a Do loop, which allows looping until a condition is no longer true or until some condition becomes true; and a For Next loop, which was shown in the example earlier in this section. And like C#, VB.NET includes a For Each statement, which allows iterating through all the elements in a value of a collection type.

VB.NET includes a While loop, a Do loop, a For...Next loop, and a For Each loop

VB.NET also includes a goto statement, which jumps to a labeled point in the program, and a few more choices. The innovation in the .NET Framework doesn't focus on language control structures (in fact, it's not easy to think of the last innovation in language control structures), and so VB.NET doesn't offer much that's new in this area.

Other VB.NET Features

The CLR provides many other features, as seen in the description of C# earlier in this chapter. With very few exceptions, the creators of VB.NET chose to provide these features to developers working in this newest incarnation of Visual Basic. This section looks at how VB.NET provides some more advanced features.

VB.NET exposes most of the CLR's features

Working with Namespaces

As mentioned in Chapter 3, namespaces aren't directly visible to the CLR. Just as in C#, however, they are an important part of writing applications in VB.NET. As shown earlier in the VB.NET example, access to classes in .NET Framework class library namespaces looks just the same in VB.NET as in C#. Because the Common Type System is used throughout, methods, parameters, return values, and more are all defined in a common way. Yet how a VB.NET program indicates which namespaces it will use is somewhat different from how it's done in C#. Commonly used namespaces can be identified for a module with the Imports statement. For example, preceding a module with

VB.NET's Imports statement makes it easier to reference the contents of a namespace

 Imports System 

would allow invoking the System.Console.WriteLine method with just

 Console.WriteLine( . . .) 

VB.NET's Imports statement is analogous to C#'s using statement. Both allow developers to do less typing. And as in C#, VB.NET also allows defining and using custom namespaces.

Handling Exceptions

One of the greatest benefits of the CLR is that it provides a common way to handle exceptions across all .NET Framework languages. This common approach allows errors to be found in, say, a C# routine and then is handled in code written in VB.NET. The syntax for how these two languages work with exceptions is different, but the underlying behavior, specified by the CLR, is the same.

Like C#, VB.NET uses Try and Catch to provide exception handling. Here's a VB.NET example of handling the exception raised when a division by zero is attempted:

As in C#, try/catch blocks are used to handle exceptions in VB.NET

 Try     X = Y/Z Catch     System.Console.WriteLine("Exception caught") End Try 

Any code between the Try and Catch is monitored for exceptions. If no exception occurs, execution skips the Catch clause and continues with whatever follows End Try. If an exception occurs, the code in the Catch clause is executed, and execution continues with what follows End Try.

As in C#, different Catch clauses can be created to handle different exceptions. A Catch clause can also contain a When clause with a Boolean condition. In this case, the exception will be caught only if that condition is true. Also like C#, VB.NET allows defining your own exceptions and then raising them with the Throw statement. VB.NET also has a Finally statement. As in C#, the code in a Finally block is executed whether or not an exception occurs.

VB.NET offers essentially the same exception handling options as C#

Using Attributes

Code written in VB.NET is compiled into MSIL, so it must have metadata. Because it has metadata, it also has attributes. The designers of the language provided a VB-style syntax for specifying attributes, but the end result is the same as for any CLR-based language: Extra information is placed in the metadata of some assembly. To repeat once again an example from earlier in this chapter, suppose the Factorial method shown in the complete VB.NET example had been declared with the WebMethod attribute applied to it. This attribute instructs the .NET Framework to expose this method as a SOAP-callable Web service, as described in more detail in Chapter 7. Assuming the appropriate Imports statements were in place to identify the correct namespace for this attribute, the declaration would look like this in VB.NET:

A VB.NET program can contain attributes

 <WebMethod()> Public Function Factorial(ByVal F _ As Integer) As Integer Implements IMath.Factorial 

This attribute is used by VB.NET to indicate that a method contained in an .asmx page should be exposed as a SOAP-callable Web service. Similarly, including the attribute

 <assembly:AssemblyCompanyAttribute("QwickBank")> 

in a VB.NET file will set the value of an attribute stored in this assembly's manifest that identifies QwickBank as the company that created this assembly. VB.NET developers can also create their own attributes by defining classes that inherit from System.Attribute and then have whatever information is defined for those attributes automatically copied into metadata. As in C# or another CLR-based language, custom attributes can be read using the GetCustomAttributes method defined by the System.Reflection namespace's Attribute class.

Attributes are just one more example of the tremendous semantic similarity of VB.NET and C#. While they look quite different, the capabilities of the two languages are very similar. Which one a developer prefers will be largely an aesthetic decision.

VB.NET and C# offer very similar features

Why Provide All of These Languages?

Microsoft says that more than twenty languages have been ported to the CLR. Along with the languages shipped by Microsoft itself, programmers will have plenty of options to choose from. Yet given the CLR's central role in defining these languages, they often have much in common. What's the real benefit of having multiple languages based on the CLR?

There are two key advantages. First, the existing pre-.NET population of Windows developers is split into two primary language camps: C++ and Visual Basic. Microsoft needs to move both groups of developers forward, and both certainly have some attachment to their language. Although the semantics of the CLR (and of languages built on it such as C# and Visual Basic.NET) are different from either C++ or Visual Basic 6, the fundamental look of these new languages will be familiar. If Microsoft chose to provide only, say, C#, it's a safe bet that developers who were wedded to Visual Basic 6 would probably be resistant to moving to .NET. Similarly, providing only a CLR-based language derived from Visual Basic wouldn't make C++ developers very happy. People who write code get attached to the oddest things (curly braces, for example), and so providing both C# and Visual Basic.NET is a good way to help the current Windows developer population move forward.

The second benefit in providing multiple languages is that it gives the .NET Framework something the competition doesn't have. One complaint about the Java world has been that it requires all developers always to use the same language. The .NET Framework's multilingual nature offers more choice, so it gives Microsoft something to tout over its competitors.

In fact, however, there are some real benefits to having just one language. Why add extra complexity, such as a different syntax for expressing the same behavior, when there's no clear benefit? Java's one-language-all-the-time approach has the virtue of simplicity. Even in the .NET world, organizations would do well to avoid multilanguage projects if possible. This isn't the problem it was with Windows DNA, since code written in different CLR-based languages can interoperate with no problems. Developers who know C# should also have no trouble understanding VB.NET, and vice versa. Still, having two or more separate development groups using distinct languages will complicate both the initial project and the maintenance effort that follows. It's worth avoiding if possible.

In the end, the diverse set of languages announced for the .NET Framework probably won't matter much. Because of Microsoft's strong support, expressed most powerfully in Visual Studio.NET, C# and Visual Studio.NET will be dominant for creating new CLR-based applications. The other languages might be interesting for universities, but for professional developers, good tools are essential. Most Windows developers today believe that Visual Studio is the best tool for building code on Windows. Just as in the pre-.NET world, I expect Visual Studio.NET and the languages it supports to be the dominant choices for Windows developers.

< BACK  NEXT >


Understanding. NET. A Tutorial and Analysis
Understanding .NET: A Tutorial and Analysis (Independent Technology Guides)
ISBN: 0201741628
EAN: 2147483647
Year: 2002
Pages: 60

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net