What's New in VB 2.0

Jun 8, 11:00 pm

Article Author: Saurabh Nandu
.NET 3.5 Books

Introduction


In this article we will overview the main new features that have been added to the Visual Basic .NET language for .NET 2.0, including:


  • XML documentation

  • Generics

  • Operator overloading

  • Partial classes

  • The Using Statement

  • Properties with Mixed Access Levels

  • New Unsigned data types

  • The Continue keyword

System Requirements


This article is based on the Beta2 version of .NET 2.0. This version is currently available for download to MSDN Subscribers and the Beta2 CD’s are available to Order in many countries from http://www.microsoft.com/betaexperience. The version of the .NET Framework is v2.0.50215 just in case you want to check the version installed on your computer is the right one! This version has been released with a Go Live license by Microsoft permitting companies to build production applications with Beta2.


XML Documentation


Until now, direct source code documentation was reserved for C# developers. With the assistance of tools like VB.DOC, it was possible to integrate comments in Visual Basic .NET, too; however, this was challenging, especially because no compiler or IntelliSense support was available. This will change with the eighth version of Visual Basic. From now on, code comment functionality is supported directly. This results in a simplified way to write comments and also ensures that references within the documentation are being validated.


The comments have to start with the familiar comment character ( ) three times i.e. ‘’‘ . After that, you can use the same XML tags as in C#. The compiler provides the new /doc option and generates the XML file, which is necessary for tools like NDoc to generate .CHM or MSDN style documentation files. Figure 1 shows such a file.



Imports Microsoft.VisualBasic
‘’‘ <summary>That’s my little foo class</summary>
Public Class Foo ‘’‘ <summary>These methods return the text passed as parameter</summary> ‘’‘ <param name="Text">Text to be returned</param> ‘’‘ <returns>Returns the string passed as <paramref name="Text"/> parameter</returns> Public Function ReturnSomeString(ByVal Text As String) As String Return Text End Function
End Class



Figure 1. An XML documentation file for VB code


Generics


Generics isn’t a new invention from Microsoft, it already exists in C++. The idea is to develop universal classes with a special syntax to accept the type as a parameter, all code in the universal class works with the special parameter. At runtime the JIT compiler create a separate copy of the class for every type that your code specifies when using the generic class. Hence the JIT Compiler does the work to duplicate the class structure for different types rather than the developer. The new version of Visual Basic .NET supports generic data types in the same way as C#, but with a slightly different syntax. In VB .NET, this involves the new Of keyword, which has to be specified at the definition of generic type during class declaration. You also need the keyword whenever you use the generic type. Constraints are defined through the As keyword, which you already know from another context. The following code demonstrates .a generic MyList class that can be used to store collections of specific reference or value types. For the sake of simplicity I use an ArrayList object inside the MyList class to store the collection, – this means the MyList class isn’t really doing more then reproduce functionality already available through collection classes, notably ones that Microsoft has supplied in the new System.Collections.Generic namespace, but this example will do to demonstrate how to define a generic class.



Imports System.Collections
Public Class MyList(Of ItemType) Dim list As ArrayList = New ArrayList() Public Sub Add(ByVal item As ItemType) list.Add(item) End Sub Default Public Property Items(ByVal index As Integer) As ItemType Get Return list.Item(index) End Get Set(ByVal value As ItemType) list.Insert(index, value) End Set End Property
End Class
Module Module1 Sub Main() Dim list As MyList(Of Integer) = New MyList(Of Integer) list.Add(1) list.Add(2) list.Add(3) list.Add("This is a string") ‘ Throws a runtime error End Sub
End Module


You can see from this code that MyList exposes a Add() method to add new objects to the collection as well as a default Item property to access the members of the collection. However the interesting aspect of the class is that the class definition itself has a generic parameter ItemType “ this is a placeholder for the type of the object to be stored in each MyList instance. You can see how this is used in the Module1 ‘s Main sub in which we create a new instance of the MyList class designed to store a list of integers.



Dim list As MyList(Of Integer) = New MyList(Of Integer)


If you observe this syntax, Of Integer is provided both while declaring the variable as well as while creating an instance. This will create a new instance of the class MyList with the parameter of type Integer as the argument. Now the list will only accept parameters of type Integer when you call the Add method of the list variable. If any other type is passed an exception will be raised.


Generic types are very useful while declaring collection classes. As noted earlier, Microsoft has provided a complete set of Generic collections under the System.Collections.Generic namespace. It’s highly recommended that you use the collections defined by Microsoft where possible rather than creating your own. Although Generics have other uses besides collections, you may well find that collections is the most common scenario in which you use them, and for that you should find the Microsoft-supplied generic classes are adequate for most situations.


Using Generic classes speeds up the time required to write implementations of type specific collections promoting code reuse. Also it avoids unnecessary boxing/unboxing overheads like in the case where we would store integers in an ArrayList object. Now if you use a generic collection the cost of boxing is not paid.


Generics have been implemented in the Common Language Runtime instead of just the language compilers thus enabling full Reflection support during runtime for generic types.


Operator Overloading


Like C#, VB .NET now supports operator overloading. It’s very useful while creating your own framework objects that need to expose the same syntax as primitive types regarding operations.


Unary and Binary Operations


For example suppose you have defined a structure, Vector2D , to hold 2d vector instances. And suppose you want to be able to write code like



Dim v1 As Vector2D
Dim v2 As Vector2D
Dim v3 As Vector2D
‘ code to initialize v1 and v2
v3 = v1 + v2


In this next code block, several overloaded operators are defined to compare, add, and subtract two instances of a 2d Vector “ these operators will allow you to write code like that just presented (specifically it’s the Operator + definition that allows you to write the exact code just listed).



Imports System
Public Structure Vector2D Public X As Integer Public Y As Integer Public Shared Operator +(ByVal p1 As Vector2D, ByVal p2 As Vector2D) As Vector2D Dim p As Vector2D = New Vector2D p.X = p1.X + p2.X p.Y = p1.Y + p2.Y Return p End Operator Public Shared Operator -(ByVal p1 As Vector2D, ByVal p2 As Vector2D) As Vector2D Dim p As Vector2D = New Vector2D p.X = p1.X – p2.X p.Y = p1.Y – p2.Y Return p End Operator Public Shared Operator =(ByVal p1 As Vector2D, ByVal p2 As Vector2D) As Boolean Return ((p1.X = p2.X) AndAlso (p1.Y = p2.Y)) End Operator Public Shared Operator <>(ByVal p1 As Vector2D, ByVal p2 As Vector2D) As Boolean Return ((p1.X <> p2.X) OrElse (p1.Y <> p2.Y)) End Operator
End Structure


All operators are implemented as methods and are Shared by definition. Be aware that some operators have to exist in pairs, i.e. if you if you wish to overload either one of the operators in a pair, then you must overload both corresponding operators. Some pairs are


  • = and <>

  • < and >

  • >= and <=

  • IsTrue and IsFalse

The operators And , Or , Not , and Xor are supported as well.


Custom Type Conversions


Custom type conversions can also be defined, as custom operators. Two new keywords are available to separate implicit (and therefore free of loss) conversion from explicit conversion: Widening and Narrowing . In the following code, you find two structures, Vector2D and Vector3D . The latter class differs from Vector2D by virtue of having an extra field, Z , which is lost on converting to a Vector2D . Let’s assume we want to define conversion operators between these classes, implicitly in one direction and explicitly in the other.


Custom type conversions are implemented using the CType operator as illustrated in this code.



Public Structure Vector2D
    Public X As Integer
    Public Y As Integer
End Structure
Public Structure Vector3D Public X As Integer Public Y As Integer Public Z As Integer Public Shared Widening Operator CType(ByVal p1 As Vector2D) As Vector3D Dim p2 As New Vector3D p2.X = p1.X p2.Y = p1.Y Return p2 End Operator Public Shared Narrowing Operator CType(ByVal p1 As Vector3D) As Vector2D Dim p2 As New Vector2D p2.X = p1.X p2.Y = p1.Y Return p2 End Operator
End Structure


Partial Classes


Partial classes is the concept of breaking the definition of a class into multiple physical files. During compilation the VB.NET compiler places all the files that comprise a class together and compiles them. A strong motivation for this functionality was to separate VS. 2005 IDE generated code and user added code by keeping them in separate files. As you’ll be aware, in order for the IDE to correctly some project types, it needs to reserve certain blocks of code within the class for its own use. In earlier versions of Visual Studio, this code was in the same file as the developer’s own code, which would not only clutter the file, but also risked VS mangling the developer’s code code if he accidentally placed it in the VS-reserved blocks. With Partial classes all IDE generated code is stored in a separate file, developer-created code is kept in a separate file and they get combined together during compilation. If you do wish to view the VS-generated code, you’ll normally find it in a hidden file, so selecting do Show All Files in your project should reveal the code.


Having said all that, partial classes can be used by developers too. For example, the feature makes it possible for multiple developers to work simultaneously on the same class, plus it can be helpful to break down large classes across different files for manageability. The required new keyword to define a partial class, is Expands . Unlike in C#, the main part of the class has to be defined as usual. Only the additional partial classes have to be marked with the Expands keyword, and they don’t need any modifiers.



‘ file foo1.vb
Public Class Foo Public Sub SomeMethod() End Sub
End Class
‘ file foo2.vb
Expands Class Foo Public Sub AnotherMethod() End Sub
End Class


Separation into several files is supported for and structures, too.


The Using statement


There is one key mistake that many novice users of managed languages such as VB.NET often make. They fail to differentiate between unmanaged resources and memory management of managed resources. The .NET Framework’s Garbage Collector takes care of managed memory management largely relieving the user from the need to write code to perform that task, but the .NET Framework does rely on the programmer to manage unmanaged resources.


Unmanaged resources include things like database connections, network sockets, file handles, graphics handles etc. “ these not automatically freed by the garbage collector, instead the programmer needs to explicitly call the Dispose() method on objects that hold unmanaged resources in order to release each resource. In VB.NET 2003 we had to use the Try-Finally block to ensure that after a unmanaged resource is used it’s always freed (in the Finally ) block. Calling Dispose() in the Finally block would guarantee that even if an exception gets thrown, the Dispose() method would still be called and the resource freed.


On the other hand, VB.NET 2.introduces the new Using statement that makes resource management easier. Any object that is declared in a Using block is guaranteed to be freed in the end of the Using block. The idea is simply “ you put a Using block in your code and the VB compiler will under the hood convert it to a Try-Finally block containing a Dispose() statement.


The following code shows how to code Using statements “ it in fact shows three nested such statements.



 Sub DataAccess()
‘ Using block for the Connection
Using sqlCon As SqlConnection = New SqlConnection("")
‘ Using block for Command
Using sqlCmd As SqlCommand =
New SqlCommand("Select * from Authors", sqlCon)
sqlCon.Open()
‘ Using block for SqlDataReader
Using sqlDataReader As SqlDataReader = sqlCmd.ExecuteReader()
While sqlDataReader.Read()
Console.WriteLine(sqlDataReader.GetString(0))
End While
End Using ‘ Auto Dispose the DataReader
End Using ‘ Auto Dispose Command
End Using ‘ Auto Dispose Connection


End Sub



In the above code snip for the DataAccess() sub you can see normal code to create the Connection , Command and DataReader objects to read data from a database. I have used nested Using blocks so that the runtime calls Dispose() against each relevent object as it goes out of scope, freeing that object’s unmanaged resources.


Properties with Mixed Access Levels


In VB.NET 2003 you had properties but the access levels on both the Get and Set accessors had to be the same. In VB 2005 Microsoft introduces properties with mixed access levels so you can provide different access modifiers for getting and setting the property:



    Dim userAccountNumber As Integer = 100023
    Public Property AccountNumber() As Integer
        Get
            Return userAccountNumber
        End Get
        Private Set(ByVal value As Integer)
            userAccountNumber = value
        End Set
    End Property


This code snippet defines a public property AccountNumber . This property has a public get accessor so any consumer of the class can get the AccountNumber . But the set accessor has been defined as private making sure that only code from within the class that contains the property can directly change the value of this property.


There are some rules defined for this new functionality to work.


  1. You cannot define these accessors for interface members.

  2. You can only define the access modifier on either get or set accessor, not both. The other accessor gains the accessibility of the property.

  3. The accessor needs to have more restrictive access than the access modifer specified for the property.

  4. If you are overriding a property in your derived class then similar access modifiers need to be applied.

New Unsigned Data Types


The new version of VB .NET comes with an extended pool of compiler-recognized data types represented by keywords “ this brings the VB datatypes up to the level of C#, with all C#-recognized types also recognized by VB and vice versa. The new types can be used to make your programs efficient or more self-documenting by your selecting the right storage model for your variables. The new types are:


  • SByte “ Small Byte (signed 8-bit (1-byte) integers ranging in value from -128 through 127)

  • UInteger “ Unsigned Integer (unsigned 32-bit (4-byte) integers ranging in value from 0 through 4,294,967,295 )

  • ULong “ Unsigned Long (unsigned 64-bit (8-byte) integers ranging in value from 0 through 18,446,744,073,709,551,615)

  • UShort “ Unsigned Short (unsigned 16-bit (2-byte) integers ranging in value from 0 through 65,535)

You can use the usual widening and narrowing operators to type cast these data types into signed types such as Integer, Long etc.


Please note that the new data types listed above aren’t CLS compliant – this means that in principle there is no guarantee that other managed languages will recognize them, although in practice that will rarely be an issue since the most common other managed languages, C# and C++, will do.


The Continue Keyword


Continue is a useful new keyword “and another feature that C# developers have been used to, now available in VB. It allows you to immediately complete the current iteration of a loop and jump into the next iteration. The Continue keyword can be used with For , Do , and While loops. In nested loops of different types, the desired loop could be specified by a suffix-for example, Continue For . You can see how Continue works in the code snippet below, which is designed to display the names of unpaid vendors. We’ve defined a Vendor class and a Module Module1 . In the Main sub we add a list of vendors to a generic List object. This is then passed to a For loop. In the for loop is check if the vendor is paid, if so then the loop is continued. If not then the name of the vendor is printed.



Public Class Vendor
   Public IsPaid As Boolean
   Public Name As String
   Sub New(ByVal paymentStatus As Boolean, ByVal vendorName As String)
      IsPaid = paymentStatus
      Name = vendorName
   End Sub
End Class
Module Module1 Sub Main() Dim vendorList As List(Of Vendor) = New List(Of Vendor) vendorList.Add(New Vendor(False, "ABC Sales Ltd")) vendorList.Add(New Vendor(True, "ZXY World Ltd")) vendorList.Add(New Vendor(True, "WED InfoSystems")) vendorList.Add(New Vendor(False, "MyCorp Ltd")) For counter As Integer = 0 To vendorList.Count – 1 ‘ If the vendor is paid don’t do any more processing ‘ on this vendor If (vendorList.Item(counter)).IsPaid Then Continue For ‘ Print names of unpaid vendors Console.WriteLine((vendorList.Item(counter)).Name) Next counter End Sub
End Module


Conclusion


In the first version of VB .NET there were quite a few missing features in comparison to C#. The upcoming second version now measures up to C#, quite well, essentially containing everything of significance that was in C# 1.0, as well as containing some of the new C# 2.0 features. Besides core features like XML documentation, generics and operator overloading there are also some other very useful additions including new keywords to assist in program execution flow and new data types. Hopefully this article has given you a good idea of the main improvements. It’s perhaps worth commenting that there are also a good number of enhancements to explore in the VB.NET 2005 IDE which we haven’t covered.

Founders at Work

Commenting is closed for this article.