Visual Basic .NET 2003 Language Changes
Microsoft Developer Network
Summary: Duncan Mackenzie provides an overview of the language changes included in the 2003 release of Visual Basic® .NET. (7 printed pages)
With the upcoming release of Visual Basic .NET 2003, the language has received two additions: the ability to initialize loop control variables in For/For Each loops and two new bitshift operators. No changes have been made to the language that will break compatibility with the original release of Visual Basic .NET.
For and For Each loops each require control variables which represent the index of the loop in the case of the For loop or are populated with an element of an expression in the case of For Each loop. In earlier versions of Visual Basic .NET (and pre-.NET versions of Visual Basic), these control variables had to be declared before they could be used in the loop statement. An example of declaring and then using a control variable in both the For and For Each loops is shown in the following listing.
Dim counter As Integer For counter = 0 To 10 Console.WriteLine(counter) Next Dim drive As String For Each drive In Environment.GetLogicalDrives() Console.WriteLine(drive) Next
Now, with the changes in the Visual Basic .NET 2003 language, you can declare your control variable as part of the loop statement itself. An example of the new syntax is shown in the following example for a simple For loop with an integer control variable that will be incremented from 0 to 10.
For counter As Integer = 0 To 10 Console.WriteLine(counter) Next
The syntax for the For Each statement is essentially the same, although the type for a For loop must be a primitive numeric (Byte, Short, Integer, Long, Decimal, Single or Double), while in the case of a For Each loop the type is dependent on the particular expression being enumerated through.
For Each drive As String In Environment.GetLogicalDrives() Console.WriteLine(drive) Next
This new control variable, if defined within the For/For Each statement, is scoped to the loop block, making it unavailable outside of that code block. The scope of this new variable means that if you need access to the loop control variable outside of the loop itself, then you will need to use the pre-existing method, defining your variable prior to using it in the For or For Each statement. For example, the following code compiles successfully and outputs a value of 11 to the console:
Dim counter As Integer For counter = 0 To 10 'do nothing Next Console.WriteLine(counter)
Alternatively, if the control variable had been defined as part of the For statement, then it would be out of scope once the For loop ends. The code below will not even compile, as it results in a "Name 'counter' is not declared." error on the last line.
For counter As Integer = 0 To 10 'do nothing Next Console.WriteLine(counter)
This new language feature provides a couple of benefits. While it is certainly a convenience and a time saving feature for developers, it also creates cleaner code because control variables are defined at the most specific possible scope and are therefore firmly associated with the appropriate loop.
It is possible to write programs for your entire life and never need to use a bit shift operator, but if you are involved in mathematical programming, such as cryptography or graphics, then you will probably use them quite often. In addition to complex math, bit shifting is often used when working with older code, including the Win32 API, as developers would take a single larger data type, such as a 32-bit Integer value, and use that space to store multiple values, such as two 16 bit values.
There are two operators:
- << for shifting a specified number of bits to the left (towards the "high order" bits)
- >> for shifting to the right.
If a shift operation causes some number of bits to go outside of an underlying data type, then those bits are discarded. Empty bit positions created by the shift operation are always filled with 0s in a left shift operation and in a positive right shift operation. If a negative number of bit places is requested in a right shift operation (
myNumber >> -4), then the vacated bit positions are filled with 1s.
The following diagram illustrates what happens when a 16-bit integer is shifted four places to the right. The four "low order" bits are discarded and the four "high order" bit positions are filled with 0s.
Figure 1. Shifting requires filling in empty bit positions
Figure 1 corresponds to the following Visual Basic .NET code:
Dim originalValue, newValue As Int16 originalValue = 21282 newValue = originalValue >> 4 Console.WriteLine(newValue)
More information on the specific working of these operators is available in the Visual Basic .NET Language Reference, part of the .NET Framework SDK that ships with Visual Basic .NET 2003. If you are interested in a more general reference on the concept of bit shifting, check out this online tutorial. It is aimed at game programming, but the concepts are the same regardless of what you are planning to use this technique for.
As I mentioned earlier, one of the uses for bit shifting was for interoperating with code where a single value, such as a 32-bit integer, has been used to store two or more independent values. This was a pretty common technique at one point, and it is even used extensively when working with the Win32 API. In the code below, I use bit shifting to break apart an RGB (color) value. RGB values are stored as three 8-bit values, leading to the term 24-bit color, and representing red, green and blue respectively.
Figure 2. RGB values are three bytes (8-bit values) combined into a single 24-bit value
To pull out these three values (red, green, and blue) in the most effective manner requires the use of two different binary operations. The first is bit masking, combining one binary value with another to isolate the specific bits we are interested in. In Visual Basic .NET we can accomplish this using the AND keyword. Once we have the appropriate bits masked, we then use bit shifting to move them over into the lower eight bits of our value.
Dim myFavoriteColor As Integer = 16773077 Dim R, G, B As Byte R = myFavoriteColor >> 16 G = (myFavoriteColor And &HFF00) >> 8 B = (myFavoriteColor And &HFF)
For the blue value we can just mask with the hex value FF so that only the first 8 bits are included in the result of the mask, producing 213 or D5 in Hex. For green, we'll mask with FF00 to include only the middle eight bits, and then bit shift over another eight positions to obtain a result (239/EF). For red, no masking is required; simply shifting sixteen positions over will force the lower sixteen bits to be discarded and we will have our red byte (255 or FF).
Note Before Visual Basic included bit shift operators, you could still do these same calculations using multiplication and division — dividing by 2^16 is the same as bit shifting right sixteen positions; multiplying by 2^16 is the same as shifting left sixteen positions — but bit shifting is a much faster method to accomplish the same results. I did a quick test, comparing the code above to the same routine written using division, and I found bit shifting to be approximately five times faster in this situation.
I chose RGB values as an example because it is a fairly common conversion, but it is worth noting that if your original value is actually a Win32 color value, an OLE color value or an HTML color string (from a web page) you can use the methods in the System.Drawing.ColorTranslator class to avoid having to do the conversion manually.
Dim myFavoriteColor As System.Drawing.Color myFavoriteColor = System.Drawing.ColorTranslator.FromHtml("#FFEFD5")
The addition of bit shifting to the language completes Visual Basic's set of binary operators and simplifies a variety of mathematical calculations that you may need to perform.
Visual Basic .NET 2003 does not include major changes to the underlying language; there are merely some useful additions to an already solid set of features. For full details on the Visual Basic language, check out the full specification in the .NET Framework SDK documentation. The specification does not yet include these two new Visual Basic .NET 2003 features, but they are coming soon.