Sie sind auf Seite 1von 58

Differences between VB6 and VB.

NET
Compatibility
VB6 and VB.NET can run on the same computer.
Inheritance
You can derive a class from a parent class.
Structured Error Handling
There will be some kind of more structured error handling, though I don't know
the details yet.
Coexistance
You should be able to run VB6 and VB.NET on the same computer.
Upgrading
When you open a VB6 program in VB.NET, a Migration Wizard appears to help
you convert it into VB.NET. There are a lot of changes, however, so you will
probably still need to do a fair amount of work.
Control Anchors
You can anchor a control, to the lower left corner of the form for example, so you
don't need to reposition it in Form_Resize.
Easy Delpoyment
You can install executables and components buy copying them into the right
directory. No more messing with Regsvr32.
New Forms
Visual Basic forms become Windows forms.
No PrintForm
Windows forms do not have PrintForm. I don't know what we're supposed to use
instead.
Unified IDE
All Microsoft languages use the same IDE. You can debug an OCX written in
C++ while running it in a VB.NET program.
Extensibility Model
The new extensibility model applies to the IDE universally. That means you can
write Add-Ins in VB.NET and use them in C#.
GDI+
The GDI (Graphics Device Interface) has new functions including Alpha
blending, anti-aliasing, and support for more file formats.
ADO.NET
Improved performance.
No DAO/RDO Binding
VB.NET does not support DAO or RDO data binding, Data controls, or the RDO
User Connection.
Object type

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


The Variant type is disappearing. The Object type can now hold a primitive
datatype, Empty, Nothing, Null, or a reference to an object.
Integer, Short
The 16-bit Integer type is now called Short. The 32-bit Long type is now called
Integer.
"Easier" Property Procedures
Property Get and Set procedures now look like this:
Property MyProperty() As Short
Get
m_MyProperty = MyProperty
End Get
Set
m_MyProperty = Value
End Set
End Property
I don't know why Microsoft thought we couldn't handle the old system.
No Parameterless Defaults
You can no longer say Text1 = "Hello". You must say Text1.Text = "Hello".
True = 1
True no longer equals -1. Now it equals 1.
Bitwise Operators
And, Or, Not, and Xor not are Boolean operators. The bitwise versions are
BitAnd, BitOr, BitNot, and BitXor.
Short-circuit Evaluation
When VB6 executes this statement, both Function1 and Function2 are called no
matter what value Function1 returns:
If Function1() And Function2() Then ...
In VB.NET, Function2 is not called if Function1 returns False.
No Null Propogation
Any VB6 statement that involved a Null value was Null. For example, Null & "x"
= Null. In VB.NET, statements involving Null generate a type mismatch error.
Zero-Based Arrays
All arrays are zero-based. You can no longer say Dim X(1 To 10) As Integer.
No Option Base
The Option Base statement no longer exists (since all arrays are zero-based).
No Fixed-Length Strings
There are no more fixed-length strings.
No Fixed-Size Arrays in UDTs
When you make a user-defined type (UDT), arrays should be undimensioned.
You ReDim the array after creating an item of this type.
No Def<Type>
These statements no longer exist.
No Computed GoTo
This statement no longer exists.
No GoSub/Return
These statements no longer exist.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


No VarPtr, ObjPtr, StrPtr, etc.
These statements no longer exist.
No LSet
This statement no longer exists.
No As Any
You cannot use As Any in API declarations. You must make separate declarations
for each data type you will pass to the API function.
No OLE Container
The Windows form does not support this control.
No Shape or Line Controls
These no longer exist.
New Graphics Methods
New methods replace Circle, CLS, PSet, Line, and Point.
Timer Interval
Setting a Timer's Interval to 0 does not disable it.
Context Menus
Windows forms have a main menu and a separate context menu used for popups.
No DDE
Windows forms do not support DDE.
New Drag and Drop
Drag and Drop still exists but is different.
New Clipboard
Improved clipboard functions.
Name Property
The Name property is no longer available at run time.

Survey
Here are the results of a survey I took on 4/21/01. Comments people made about
questions 3 and 4 are at the end.
1. Are you using the VB.NET beta?
2</TD
Yes
< TR>
No 15
2. Do you plan to use Beta 2?
3</TD<
Yes
TR>
Probably 1
Maybe 4
9</TD<
No
TR>

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


3. Do you plan to use VB.NET when it is finally released?
9</TD<
Yes
TR>
Don't know 6
3</TD<
No
TR>
4. Do you want to see more VB.NET examples?
Yes 5</TD< TR>
13</TD<
No
TR>

Comments
Here are comments people made for questions 3 and 4.
3. Do you plan to use VB.NET when it is finally released?
No. I'm going to stay with VB6. This, because I am one of those rare, and becoming even
more rare, individuals who use computers for *computing* (i.e., scientific computation).
I can not care less about being able to create Internet-or Intranet-related applications, so
there is no need for me to suffer through the agonies of coming in line with an almost
entirely new development system. Furthermore, I suspect that, knowing Microsoft, the
current Beta version is really an advanced Alpha, and that when the first commercial
version hits the streets, that's when the *real* beta-testing will begin. This is cheaper for
Microsoft. I know that this will doom me to living out the rest of my professional days in
the ever receding backwaters, but that's Ok with me. I'm coming up on 66 years, and VB6
and VC++6 will serve me nicely for as long as I want to remain active in the profession.
Only if held at gunpoint
What choice do I have?

Yes, do I have a choice? That is the direction of the future


Not sure, from what I've been hearing and reading.
Not if I can help it. I'm so mad at Microsoft's arrogance regarding backwards
compatibility that I'm planning on switching to C++ for new projects. (Of course, I have
to learn C++ first!) The few concessions that MS has made to VB6 still won't change the
fact that all of my projects are going to require massive recoding to run under VB.NET.

MAYBE. Depends upon its popularity and support, and the Hailstorm/Passport thing (not
sure if I/we accept that yet). Right now the company and I see no need for it in any
project. I guess I’m taking my usual wait-and-see attitude. Everybody here is scratching
their heads and wondering WHAT benefit can be derived from it?????
4. Do you want to see more VB.NET examples?
Yes. At the moment I only have time which permits me to learn either XML or VB.NEt I
need to make a decision which one to choose as of Now.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


No. I'm still trying to learn VB6. From what I've read, VB.NET is a different language.

Yes, slowly. I'm just trying to understand what it is. Also, can you answer what will be
necessary to learn along with it. I gather XML will be one. Will JavaScript work with it.
That's what I mean by number 4
Yes, to find out more about it.
No. I see no reason to get all hyped up about software that isn't even on the open market
yet. As far as I am concerned, VB 6 is the latest version of VB and that is what the
examples, tips, tricks and hints should be based on.
Later on, after VB.NET has been released (and the third service pack released within 6
months after that), then our organization >>> MIGHT <<< consider using it. But
VB.NET is more like a brand new programming language than a new update of VB.
YES, I do not have time to look at it yet and I appreciate your research.
Not until I've made the switch, which will probably be never!
Yes. Even if I don't understand them. I need to get my feet wet sometime.

SURE. I figure I’ll be forced to use it someday, whether I’m ready or not. Already been
passively learning about it through the flood of e-letters stuffed into my inbox.
I've been attending the MSDN Events in Portugal and so far it looks promising (even if it
looks like a MS tailored version of J2EE). At least they are catching up...
For the developers, the .NET is "Code anyway, Run in Windows". Java in the other hand
is "Code in Java, Run anywhere"...
I'm almost ready to install Beta 1, and intend to become used to it's new paradigm. I
would like to see examples of VB.NET (mayhappen open a new layer on the site?)...
Yes, I'd like to see some after VB.NET is finally released. But, even then I'd like to focus
mainly on VB6 for a while since most people (including me) will take a while to upgrade.

Most people don't seem to like VB.NET but see it as unavoidable. You may be able to
avoid VB.NET but you will have to either stick with VB6 or learn a new language. For a
related article, see VB Users Migrating To Newer Languages Latest EDC Study Shows.
I have not commented much on the VB.NET Beta 1 in public. I'm not happy with Beta 1,
but I think it's great that Microsoft has made the Beta so widely available. I also realize
this is only a beta and that performance should improve in Beta 2 and in the final release.
I'll wait until Beta 2 before I start complaining too loudly.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Overview of Changes from VB6 to VB.NET

This article discusses the important language changes from VB6/VBScript to


VB.NET. When creating ASP.NET pages, you are required to use a .NET-
compatible programming language, such as C#, VB.NET, or JScript.NET.
However, there are some significant changes from VB6/VBScript to
VB.NET, which this article addresses. To learn more about ASP.NET in
general, be sure to check out the ASP.NET Article Index!
Also, for more information be sure to check out Microsoft's article:
Preparing Your Visual Basic 6.0 Applications for the Upgrade to Visual
Basic.NET.

Introduction
With release of Microsoft .NET platform, Visual Basic has emerged into a fully objected
oriented language (dubbed VB.NET). With these radical changes, though, the learning
curve between VB6 and VB.NET might be reasonably high even for experienced
programmers. In this article I will try to list language changes to Visual Basic along with
sample examples wherever appropriate. The list presented here may not be complete but
it does cover majority of features. If you are a VB programmer wanting to shift to
VB.NET this is a must read for you.
Note that currently (as of May 30th, 2001), ASP.NET is in Beta 1, which is freely
downloadable from www.ASP.NET. However, some of the changes discussed in this
article are changes that are proposed for the Beta 2 version, which is scheduled to be
released to the public on June 17th. These areas that are new to Beta 2 (and therefore will
not work with the Beta 1 version of ASP.NET) are marked.

Data Type Changes


The .NET platform provides Common Type System to all the supported languages. This
means that all the languages must support the same data types as enforced by common
language runtime. This eliminates data type incompatibilities between various languages.
For example on the 32-bit Windows platform, the integer data type takes 4 bytes in
languages like C++ whereas in VB it takes 2 bytes. Following are the main changes
related to data types in VB.NET:
• Under .NET the Integer data type in VB.NET is also 4 bytes in size.
• VB.NET has no currency data type. Instead it provides decimal as a replacement.
• VB.NET introduces a new data type called Char. The char data type takes 2 bytes
and can store Unicode characters.

• VB.NET do not have Variant data type. To achieve a result similar to variant type
you can use Object data type. (Since every thing in .NET - including primitive
data types - is an object, a variable of object type can point to any data type).

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


• In VB.NET there is no concept of fixed length strings.

• In VB6 we used the Type keyword to declare our user defined structures. VB.NET
introduces the structure keyword for the same purpose. The rest of the syntax is
same. That is:
Structure MyStruct1
...
End Structure
Declaring Variables
Consider this simple example in VB6:
Dim x,y as integer
In this example VB6 will consider x as variant and y as integer, which is somewhat odd
behavior. VB.NET corrects this problem, creating both x and y as integers. Furthermore,
VB.NET allows you to assign initial values to the variables in the declaration statement
itself:
Dim str1 as string="hello"
VB.NET also introduces Read-Only variables. Unlike constants Read-Only variables can
be declared without initialization but once you assign a value to it, it can not be changed.
'no initialization here
Dim readonly x as integer

'in later code


x=100

'now x can't be changed


x=200 '***** error *********
Arrays
With VB6, you could programmatically define the lower and upper bounds of an array. In
VB.NET, however, an array's lower bound is always zero. Also, when defining an array
like so:
Dim aStates(50) as String
in actuality, 51 elements are being created, with 0 as the lower bound and 50 as the
upper bound! (Note that in Beta 1 of the VB.NET compiler, the above statement would
create 50 elements, from bounds 0 through 49.)
In Part 1 we examined VB.NET's changes to data types, variable declaration, and arrays.
In this part we'll continue our examination of VB.NET's syntax changes.
Variable Scoping
Consider following VB6 code:
If x=y then
Dim z as integer
' other code
End If

z=100 'Outside of If ... Then block

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


The above code runs perfectly with VB6 because there is no block-level variable scoping.
(Block-level scoping occurs in other modern programming languages (such as C++).
Variables defined within statement blocks, such as the variable defined in the If ... Then
block, fall out of scope when the statement block ends. Therefore, accessing z outside of
the If ... Then block where it's defined, would cause an error in modern programming
languages.) VB.NET, contrary to VB6, employs block-level variable scoping.
The Set and Let Statements
In VB6 you must use the Set statement to assign an object instance to a variable. This was
necessary in VB6 because of default properties. To tell VB that we want to assign a
variable to the object itself (as opposed to the value of the object's default property) you
had to use the Set keyword. For example, in VB6:
Dim x as Variant
Dim strName as string

'Assign the value of Text1.Text to StrName


'(Text is the default property of the textbox control in VB6)
StrName=Text1

'Here we assign the actual Textbox object to the variable x


'Note that we use the Set keyword so VB knows we want to assign
'to x the object itself instead of the default property
Set x=Text1
In VB.NET, however, there are no default properties allowed (except for parameterized
properties) and hence there is no need for the Set keyword. (Likewise, the Let keyword
has been removed from the VB.NET syntax.)
Error Handling
Visual Basic has finally incorporated structured error handling. The keywords Try, Catch
and Finally make error handling easy and make VB.NET at par with languages like C++
or C#. This Try ... Catch model allows developers to place code that may cause an
exception within a Try block. If that code throws an exception (synonymous to raising an
error), the code in the Catch block is executed; the code in this block should be designed
to gracefully handle the exception.

Note that VB6's older error handling techniques (On Error Resume Next and the like) are still
supported for backward compatibility, although when writing new applications with
VB.NET you should valiantly strive not to use these old techniques. The following code
snippet illustrates various error handling techniques with VB.NET:
Try
...
Catch
...
End Try
The above code simply "catches" any exceptions caused by offending code inside the
associated Try block. VB.NET allows you to handle specific exceptions by using multiple
Catch blocks:
Try

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


...
Catch e1 as NullPointerException
...
Catch e2 as Exception
...
End Try
In addition to catching predefined exceptions you can also create your own custom
exception classes that inherit from the System.Exception base class. You can also 'Throw'
your own exceptions (similar to using the Raise method of the Err object in VB6:
If myvar < 1000 then
Throw new Exception("Business Logic Error")
End If
In Part 2 we continued our examination of VB.NET's new features, looking at varaible
scoping, default object properties, the Set and Let keywords, and error handling. In this
third and final part, we'll complete our study of VB.NET's new features.
Static Methods
VB.NET now allows you to create static methods in your classes. Static methods are
methods that can be called without requiring the developer to create an instance of the
class. For example, if you had a class named Foo with the non-static method NonStatic()
and the static method Static(), you could call the Static() method like so:
Foo.Static()
However, non-static methods require than an instance of the class be created, like so:
'Create an instance of the Foo class
Dim objFoo as New Foo()

'Execute the NonStatic() method


objFoo.NonStatic()
To create a static method in a VB.NET class, simply prefix the method definition with
the keyword Shared.
Procedures and Functions
In VB6 all the procedure parameters are passed by reference (ByRef) by default. In
VB.NET they are passed by value (ByVal) by default. Parentheses are required for
calling procedures and functions whether they accept any parameters or not. In VB6
functions returned values using syntax like: FunctionName = return_value. In VB.NET you
can use the Return keyword (Return return_value) to return values or you can continue to use
the older syntax, which is still valid.
Property Syntax
In VB6 we used Property Get and property Set/Let for creating properties in classes. The two
appeared as separate routines:
Public Property Get PropertyName() as DataType
...
End Property

Public Property Let PropertyName(value as DataType)


...

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


End Property
In VB.NET the syntax changes quite a bit. Rather than having two separate Property Get
and Property Let/Set statements, these are combined into one Property statement. Also,
within the Set portion of the Property statement the variable Value indicates the value
entered by the user when assigning a value to the indicated property.
Public [ReadOnly|WriteOnly] Property PropertyName as DataType
Get
Return m_var
End Get

Set
M_var = Value
End Set
End Property
Conclusion
There are some changes to VB.NET's semantics and syntax, but these are the most
important changes that you, as an ASP.NET developer, will come across. The most
important things to keep in mind when working with VB.NET to create ASP.NET Web
pages are:
1. Variables can be typed and are no longer all Variants. That is, if you need an
Integer variable, use Dim i as Integer instead of just Dim i. (Typing your variables
leads to tremendous performance increases over untyped variables.)
2. Remember that VB.NET requires that subroutine calls have parenthesis around
the calling parameters! That means Response.Write "Hello, World!" will generate an
error. Rather, you need to place parenthesis around the parameter you are passing
into the function: Response.Write("Hello, World!")
3. VB.NET no longer supports default properties - you must explicitly specify the
property you wish to access from an object.
4. Be careful when declaring arrays. As aforementioned, all arrays in VB.NET have
a lower bound of zero, and an upper bound of the number you specify (resulting
in one more element than you may have thought you had when creating the
array).
Happy Programming!
Visual Fred
Following are the bullets you will not see on the side of the box or the marketeer's glossy.
This list has been characterized as "sensationalistic" and, frankly, it is. The changes
proposed for this language are indeed sensational! I'd personally be ecstatic if there
weren't so many fundamental hazards facing today's functional code. New development
may be very well-served, but migration is a shaky proposition, at best.

This is a short list of some of the incompatabilities -- considered "gratuitous" to "essential"


depending who you talk to -- Microsoft plans to introduce with the roll-out of Visual Fred.
Yes, there are ways to workaround many of these issues, but the fact that workarounds are

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


needed indicates something was broken. That something, in this case, is your existing
code. In some cases, the fix will be as "simple" as using a different keyword. In others,
there may be no workaround at all.
This list is intended solely as a roadmap of the migration hazards that lie ahead. All points
are considered to be factual and correction is indeed welcome if you feel that isn't the
case! Below, I've provided links to a few sources of further information. The
incompatabilities are not listed in any particular order, other than rough groupings by type
of incompatability (visible with View-Source). Numbers are used only to offer a sense of
proportion to the length of this list.
If you're curious about the name, Visual Fred was coined by Bill Vaughn, formerly of
Microsoft. It's considered to highlight the sentiment that this really isn't VB anymore, and
perhaps should've been given a different name. Form your own opinion, after considering
the differences.
Finally, as you may have guessed, Microsoft has their own position on all this. <g> To see
their response to this list of bullets, scroll down and click the link to download a Word
document they prepared just for this site!

1. VarPtr is not supportedavailable.

2. StrPtr is not supportedavailable.

3. ObjPtr is not supportedavailable.

4. As Any is not supported for API Declares.

5. Use of ByVal/ByRef directly within API calls is not supported.

6. Private class variables are not private to the class instance.

7. Arrays may not have a lower bound other than zero.

8. Arrays are not declared using the upper bound. (Addressed in Beta2)

9. Option Base is not supported.

10. Variants are not supported. Object is now the default data type.

11. Currency is not supported.

12. Dates are not stored internally as Double values.

13. Longs are not 32-bits; they are 64-bits.

14. Integers are not 16-bits; they are 32-bits.

15. True, coerced to an Integer, is not -1, but is 1 instead. (Addressed in Beta2)

16. The Imp and Eqv operators are not supported.

17. Fixed-length Strings are not supported.

18. DefInt, DefLong, et al., are not supported.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


19. Dim may not always create procedure-level variables.

20. Redim will not create arrays not already declared.

21. Local variables are not necessarily visible (in scope) throughout a procedure.

22. VarType is not supported.

23. Empty is not supported.

24. Null is not supported.

25. IsEmpty is not supported.

26. IsMissing is not supported.

27. IsNull is not supported.

28. IsObject is not supported.

29. Let is not supported.

30. Core language constants do not have a "vb" prefix (vbRed becomes Red).

31. Terminate will not fire when an object's last reference is released.

32. Object finalization code will not execute in a predictable order.

33. Implicit object creation is not delayed until first reference.

34. Public object variables are not safe from alteration when passed as parameters.

35. Can not expose Property procedures with mixed visibility (Friend Set/Public Get).

36. Procedure parameters are not by default passed ByRef anymore.

37. ParamArray arguments are not passed ByRef anymore.

38. Property parameters may not be passed ByRef anymore.

39. Implements is not implemented the same, so must be rewritten.

40. Static is not supported as a procedure level modifier.

41. Use of As New does not force auto-reinstantiation when an object is released.

42. Parenthesis are not optional when calling procedures.

43. Set is not supported for object assignment.

44. Parameterless default properties are not supported.

45. Default values for Optional parameters are not optional.

46. Code is not compiled to native, thus making decompilation much easier.

47. Resource files have changed format and old ones are not supported.

48. LSet is not supported.

49. RSet is not supported.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


50. UDTs are not Types, but are called Structures instead.

51. UDTs are not by default contiguous blocks of memory, but are objects.

52. Enums will not be recognized unless fully-qualified.

53. While/Wend loops are not supported.

54. GoSub/Return is not supported.

55. On/GoTo is not supported.

56. On/GoSub is not supported.

57. Line numbers are not supported. Labels may be numeric.

58. Erl is not supported.

59. The MsgBox function is not supported.

60. The DoEvents function is not supported.

61. The Date statement is not supported.

62. The Time statement is not supported.

63. And, Or, XOr, and Not are not bitwise operators. (Addressed in Beta2)

64. Comparison operators are not evaluated before logical operators. (Addressed in Beta2)

65. Sqr is not supported.

66. Sgn is not supported.

67. Atn is not supported.

68. Control arrays are not supported.

69. UnloadMode detection is not offered, as QueryUnload is history.

70. ListBox controls do not offer an ItemData property.

71. ListBox controls do not offer an NewIndex property.

72. Windowless controls are not supported.

73. Image controls are not supported.

74. Shape controls are not supported.

75. Line controls are not supported.

76. OLE Container controls are not supported.

77. Label controls will not have a Caption property.

78. The Tag property is not supported. (Addressed in Beta2)

79. The ToolTipText property is not supported.

80. The TextHeight property is not supported.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


81. The TextWidth property is not supported.

82. Setting a Timer control's Interval to 0 does not disable it.

83. Top-level menus may not be used as context menus.

84. Old forms using vbPixels for Scalemode will not upgrade correctly.

85. DDE is not supported.

86. Circle is not supported.

87. Cls is not supported.

88. Line is not supported.

89. PSet is not supported.

90. Point is not supported.

91. AutoRedraw is not supported.

92. PrintForm is not supported.

93. Scale is not supported.

94. The Name property for forms and controls is not exposed at runtime. (Addressed in Beta2)

95. Print will not include a linefeed at the end of a line.

96. File I/O will not be compatible, at all, and must be rewritten.

97. Printer object methods are not automatically upgraded and must be rewritten.

98. Clipboard object methods are not automatically upgraded and must be rewritten.

99. The Err object is not shared between managed (.NET) and unmanaged (ActiveX) code.

100. The App object is not shared between managed (.NET) and unmanaged (ActiveX) code.

101. Screen.MousePointer does not have a direct replacement.

102. Webclasses are not supported.

103. DHTML projects are not supported.

104. UserControl projects are not supported.

105. ActiveX Document projects are not supported.

106. The IDE Extensibility Model is not backwardly compatible.

107. Run->Break->Edit->Continue development is not supported.

108. The Immediate window will not work in Design mode.

109. SDI will not be an option in the IDE -- MDI or nothing.

110. Debug.Print is not supported.

111. Debug.Assert is not supported.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


112. Data binding with DAO is not supported.

113. Data binding with RDO is not supported.

114. …

115. …

116. …

Microsoft Responds!
Yes, it's true. The black helicopters, er, uh, Microsoft does pay
attention to what's going on out here. They've prepared this
response especially for you to download from this site. If you see it
offered elsewhere, there's no vouching for its authenticity. I don't
want to be accused of altering anything they've said, so I'm posting
Microsoft's response in it's original Word 97/2000 format (135K,
last updated 9-Mar-01), and assume you have some way to read
that. For now, I will withhold my own comments, but I am very
interested in hearing what you think about this latest response!
Keep those cards and letters coming, folks! People are paying
attention. :-)

Further Reading
More than likely, you'll want to read more about these issues, and
what you can do to minimize their impact. Randy Birch has
collected a number of interesting articles, many from Visual Studio
developers and product managers, as well as some of the more
poignent newsgroup commentary. He's also conducting a poll
regarding your plans for migration.

Fans of Bruce McKinney (author of Hardcore Visual Basic) will


likely appreciate his insights (incites?) into the upcoming sea-
changes. Jump to his website and click on the VB.NET link for
more of his wit and wisdom.

More Details and Workarounds


Bob Butler has amassed a very good compendium of the upcoming
changes, and what they really mean to you, as well as suggestions
on how you might consider modifying your code so it may work in
the future. Bob's site is under constant construction, as he adds new
information for your benefit. Many of the not's above came directly
from his pages, and there you'll find far more details supporting the
claims made above.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Defensive Practices
Another interesting read would be that offered by Microsoft's own
migration white paper. This is the paper that convinced me of the
need to provide this very page for you, because reading it
demonstrated to me just how profound the changes were to be.

Open Sores?
The first open source decompiler and source code generator has
now been released for .NET executables. Looks like the only
protection for your source code is to house it solely on your own
servers. If it's distributed, it's wide-open. Forget the /OWNER
compiler switch, as that's only protection against willing code
breakers like ILDASM.

Parting Thoughts
"Anyway, if you really want to listen and consider other POV's,
here's mine. I personally don't use and don't like GoSub. I do
however realise that it is part of the language and other people do
use it. Forcing an incompatibility with other peoples code because I
don't use a feature is not what I would consider rational. In fact,
because it is harder for them to smoothly move into VB.NET
immediately, it has a net negative impact on the uptake and success
of the language. That will have a negative impact on me, and my
stocks. I honestly think the reality of this situation is if it's a feature
you don't use then don't worry about it, and don't ask for it to be
removed. Look at the bigger picture, and try to make decisions that
benefit all, because as a programmer community, like it or not, our
successes are in part tied to the success of the community as a
whole."
Bill McCarthy, Microsoft Visual Basic MVP, on DevX
http://www.totalenviro.com/vb7

The Transition from Visual Basic 6.0 to


Visual Basic.NET
Introduction
Microsoft Visual Basic.NET is the next version of Microsoft Visual Basic®, built from
the ground up on the .NET Framework to enable you to easily create next-generation
applications for the Microsoft Windows® operating system and the Web. With Visual
Basic.NET, it's a snap to visually develop Web applications, Web Services, Windows

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


applications, and server-side components. In addition, Visual Basic.NET delivers
XCOPY deployment of Windows applications, so you no longer need to worry about
DLL versioning issues. With Visual Basic.NET, “DLL Hell” is a thing of the past.
When designing Visual Basic.NET, we looked at the top requests of Visual Basic
developers worldwide. The Visual Basic language is now truly object-oriented and
supports implementation inheritance. The form designer supports visual inheritance and
contains new features, such as automatic form resizing, resource localization, and
accessibility support. The data tools now inherently support XML data, and the design-
time data binding works with disconnected data. In addition, Visual Basic.NET is built
directly on the .NET Framework, so you have full access to all of the platform features,
as well as interoperability with other .NET languages.
In delivering these features, we have made changes to several aspects of the product. This
document describes some of the changes from Visual Basic 6.0 to Visual Basic.NET, and
explains the motivation behind them. It also describes capabilities of the Visual
Basic.NET Upgrade Wizard, a tool provided as part of the product that will help you
upgrade your existing applications to Visual Basic.NET.
Additional information regarding the upgrade from Visual Basic 6.0 to Visual Basic.NET
can be found in the white paper Preparing Your Visual Basic 6.0 Applications for the
Upgrade to Visual Basic.NET. This paper describes the upgrade process and provides
architectural recommendations for making the upgrade as smooth as possible.

Language
Variant
Visual Variant is a special “universal” data type that can contain any kind of data except
fixed-length strings. An Object variable is used as a pointer to an object. Variant is
Basic 6.0 the default data type.
Visual The common language runtime (CLR) uses Object for the universal data type. Visual
Basic.NET Basic.NET could have continued to use Variant for the universal data type, but chose
to adopt the naming convention of the CLR to avoid confusion for cross-language
development. The type system is simplified by having only a single universal data
type. The default data type is Object.
Upgrade Variant data types are changed to Object, so the following code:
Wizard Dim x As Variant
is upgraded to:
Dim x As Object

Integer and Long


Visual Long variables are stored as signed 32-bit numbers, and Integer variables are stored
as 16-bit numbers.
Basic 6.0
Visual Long variables are stored as signed 64-bit numbers, Integer variables are stored as 32-bit numbers,
Basic.NET and Short variables are stored as 16-bit numbers. On 32-bit systems, 32-bit integer operations are
faster than either 16-bit or 64-bit integer operations. This means that Integer will be the most efficient
and fundamental numeric type.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


As some of the .NET Framework technologies are based around modern 32-bit and 64-bit
technologies, it makes sense to update the data sizes to the new technology.
Upgrade The variable types are changed, so the following code:
Wizard Dim x As Integer
Dim y As Long
is upgraded to:
Dim x As Short
Dim y As Integer

Currency
Currency
Visual Visual Basic 6.0 supports a data type. You cannot declare a variable to be
of type Decimal (although variants can have a subtype of Decimal).
Basic 6.0 Currency variables are stored as 64-bit numbers in an integer format, scaled by
10,000 to give a fixed-point number with 15 digits to the left of the decimal point and
4 digits to the right. This representation provides a range of -
922,337,203,685,477.5808 to 922,337,203,685,477.5807.
Decimal variables are stored as 96-bit signed integers scaled by a variable power of
10. The power-of-10 scaling factor specifies the number of digits to the right of the
decimal point, and ranges from 0 to 28. With a scale of 0 (no decimal places), the
largest possible value is +/-79,228,162,514,264,337,593,543,950,335. With 28
decimal places, the largest value is +/-7.9228162514264337593543950335 and the
smallest non-zero value is +/-0.0000000000000000000000000001.
Visual The Currency data type does not provide sufficient accuracy to avoid rounding
Basic.NET errors, so Decimal was created as its own data type.
Upgrade Currency data types are changed to Decimal, so the following code:
Wizard Dim x As Currency
is upgraded to:
Dim x As Decimal

Date
Visual A Date variable is stored internally in a Double format and can be manipulated as
Double.
Basic 6.0 Date variables are stored as IEEE 64-bit floating-point numbers that represent dates
ranging from 1 January 100 to 31 December 9999 and times from 0:00:00 to
23:59:59. Any recognizable literal date values can be assigned to Date variables.
When other numeric types are converted to Date, values to the left of the decimal
represent date information while values to the right of the decimal represent time.
Midnight is 0 and midday is 0.5. Negative whole numbers represent dates before 30
December 1899.
Visual Date variables are stored internally as 64-bit integers, so they cannot be manipulated
Basic.NET directly as Double. The .NET Framework provides the ToOADate and
FromOADate functions to convert between Double and Date. Representing dates as
integers simplifies and speeds up the manipulation of dates.
Upgrade Although not all cases can be detected for example, where a variant is used to store a
Wizard Date as a Double), the upgrade tool typically inserts the appropriate ToOADate or

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


FromOADate method where a Double is assigned to a Date. For example, the
following code:
Dim dbl As Double
Dim dat As Date
Dbl = dat
is upgraded to:
Dim dbl As Double
Dim dat As Date
Dbl = dat.ToOADate

Fixed-length strings
Visual Variables can be declared with a fixed-length string, except for
Public variables in a
class module.
Basic 6.0
Visual Fixed-length strings are not supported in the first version of the CLR. This support
Basic.NET will be added in a later version.
Upgrade In most cases, this is not an issue. A compatibility class provides fixed-length string
Wizard behavior, so the following code:
Dim MyFixedLengthString As String * 100
is upgraded to:
Dim MyFixedLengthString As New VB6.FixedLengthString(100)
See the white paper Preparing Your Visual Basic 6.0 Applications for the Upgrade to
Visual Basic.NET for a full discussion of this topic.

Type
The Type statement is used to define a user-defined data type.
Visual
Basic 6.0
Visual The names Type and User-Defined Type are confusing, because classes, enums, and
Basic.NET interfaces are also types that can be defined by users. Type and User-Defined Type
are vestiges of QuickBasic, in which structures and records were the only types that a
user could define. The CLR uses the name Type in a broad sense to include all data
types.
For this reason, the statement Type is changed to Structure in Visual Basic.NET
Upgrade Type statements are changed to Structure, so the following code:
Wizard Type MyType
MyVariable As Integer
End Type
is upgraded to:
Structure MyType
Dim MyVariable As Short
End Structure

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


User-defined type storage
User-defined data types can contain one or more elements of a data type, an array, or
Visual
a previously defined user-defined type. In Visual Basic 6.0, they are stored in
Basic 6.0 contiguous blocks of memory.
Visual In the CLR, user-defined types are stored in whatever format is most efficient. This
Basic.NET may or may not be a contiguous block of memory. Structures can be marked with
marshalling attributes to ensure they are passed to COM components as a contiguous
block of memory.
Upgrade APIs are marked with a TODO comment wherever you many need to add
Wizard marshalling attributes (attributes are not added automatically; they are not needed
unless you pass the structures to APIs).

True
True has a value of –1.
Visual
Basic 6.0
Visual True has a value of 1.
Basic.NET For language interoperability, a consistent representation is needed across all
languages.
Upgrade When a Boolean is coerced to a non-Boolean type, code is marked with an upgrade
Wizard warning. For example, the following code:
Dim MyBoolean As Boolean
Dim MyInteger As Integer
MyInteger = MyBoolean
is upgraded to:
Dim MyBoolean As Boolean
Dim MyInteger As Short
' UPGRADE_WARNING: Boolean MyBoolean is being converted into a numeric
MyInteger = MyBoolean

Empty
Variants are initialized to Empty, which automatically converts to zero when used in
Visual
a numeric expression, or to an empty string when used in a string expression.
Basic 6.0
Visual Object variables are initialized to Nothing, which automatically converts to zero
Basic.NET when used in a numeric expression, or to an empty string when used in a string
expression. Using Nothing instead of a special Empty value reduces complexity in
the language and allows for better language interoperability.
Upgrade Empty is converted to Nothing.
Wizard

Null and Null propagation


Null values are Variant subtypes indicating that a variable contains no valid data.
Visual

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Basic 6.0 Null values "propagate" through expressions and functions. If any part of an
expression evaluates to null, the entire expression evaluates to Null. Passing Null as
an argument to most functions causes those functions to return Null.
Visual Null propagation is not supported. The model for programming data with ADO.NET
Basic.NET is to test fields explicitly for Null before retrieving their values. Variants containing
null are marshalled into the CLR as objects of type DBNull.
Visual Basic.NET makes the rule for Null more intuitive—string functions, such as
Left(), always return a string as you would expect.
Upgrade Null values and IsNull functions are commented with an upgrade warning. For
Wizard example, the following code:
If x Is Null Then MsgBox "Null"
is upgraded to:
' UPGRADE_WARNING: Use of IsNull() detected
If IsDBNull(x) Then MsgBox "Null"

Def<Type>
Visual DefBool, DefByte, DefInt, DefLng, DefCur, DefSng, DefDbl, DefDec, DefDate,
DefStr, DefObj, and DefVar statements are used at the module level to set the
Basic 6.0 default data type for variables, parameters, and procedure return types whose names
start with the specified characters.
Visual Readability and robustness of code is improved by avoiding the use of implicit type
Basic.NET declarations.
Upgrade Explicit declarations of the variable types are inserted into the code. For example, the
Wizard following code:
DefStr a-z
Sub MySub
s = “Hello”
End Sub
is upgraded to:
Sub MySub
Dim s As String
s = “Hello”
End Sub

Local variables inside blocks


Visual Local variables are visible from the line containing the declaration to the end of the
procedure.
Basic 6.0
Visual Visual Basic.NET supports block scoping of variables. This means that a local
Basic.NET variable is visible from the line containing the declaration to the end of the block in
which the declaration appears. For example:
Sub Test(x As Integer)
If x < 0 Then
Dim y As Integer = - x

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


'...
Else
'...
End If
End Sub
The variable "y" in the example above is available only within the block in which it is
declared; specifically, it is available only from its declaration down to the Else
statement. If the variable needs to be available to the entire procedure, then it must be
declared outside of the If/Else/End If control structure.
Block scoping of variables is a feature common to many structured languages. Just as
procedure locals support structured programming by allowing definition of variables
that are private to a procedure, block-level variables support structured
decomposition by allowing definition of variables that are private to a block of code.
Upgrade If variables are declared inside a block, they are automatically moved to module-level
Wizard scope. For example, the following code:
If x =1 Then
Dim y As Integer
End If
is upgraded to:
Dim y As Integer
If x =1 Then
End If

New auto-reinstantiation
Visual A class variable declaration of the form "Dim x As New <classname>" causes the
compiler to generate code on every reference to "x". That code checks to see whether
Basic 6.0 "x" is Nothing; if it is Nothing, a new instance of the class is created. For example,
the code:
Dim x As New MyClass
'...
Call x.MyMethod()
is equivalent to:
Dim x As MyClass
'...
If x Is Nothing Then
Set x = New MyClass
End If
Call x.MyMethod()
Even after the variable is set to Nothing, it will be reinstantiated on the next call to it.
Visual A variable declaration of the form "Dim x As New <classname>" is equivalent to
Basic.NET "Dim x As <classname> = New <classname>". No special code is generated for
references to variables that are declared with this syntax.
Visual Basic.NET declarations for "As New" are far more efficient than the same
declaration in Visual Basic 6.0. For most references to such variables, the extra
overhead is unnecessary. Also, the "auto-instantiation" behavior of Visual Basic 6.0

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


is a surprise to many programmers when it is discovered.
Upgrade It is rare that this will be an issue. However, if code tries to use a class after it has
Wizard been set to Nothing, it will cause an easily detectable run-time exception. The code
can then be easily modified to instantiate a new version of the class, as in the
following example:
Dim x As New MyClass
x = Nothing
x = New MyClass

Object finalization
The COM reference-counting mechanism is used to garbage collect object instances.
Visual
When objects are not in cycles, reference counting will immediately detect when an
Basic 6.0 object is no longer being used, and will run its termination code.
Visual A tracing garbage collector walks the objects starting with the reachable references
Basic.NET stored in stack variables, module variables, and shared variables. This tracing process
runs as a background task, and, as a result, an indeterminate period of time can lapse
between when the last reference to an object goes away and when a new reference is
added.
In some cases, clients do need the ability to force an object to release its resources.
The CLR uses the convention that such an object should implement the IDisposable
interface, which provides a Dispose method. When a client has finished using an
object with a Dispose method, it can explicitly call the Dispose method so that its
resources will be released. For example, an object that wraps a database connection
should expose a Dispose method.
The tracing garbage collector can release objects in reference cycles correctly. Also,
the performance of the tracing garbage collector is much faster than the performance
of reference counting.
Upgrade In most cases, this change will not cause a problem. If you have code that holds a
Wizard resource handle open (For example., Microsoft SQL Server™ connections or file
handles), you should explicitly close the handle. The problem is easily detected and
causes a run-time error.

Arrays
Visual Arrays can be defined with lower and upper bounds of any whole number. The
Option Base statement is used to determine the default lower bound if a range is not
Basic 6.0 specified in the declaration.
Visual To enable interoperability with other languages, all arrays must have a lower bound
Basic.NET of zero. This makes the Option Base statement no longer necessary.
Upgrade During upgrade, you have the option to treat your arrays as zero lower bound, or to
Wizard change them to an array compatibility class, as in the following example:

Dim a(1 To 10) As String


is upgraded to:
Dim a As System.Array = VB6.NewArray(GetType(String), 1, 10)

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


ReDim
Visual Basic 6.0 has a distinction between fixed-size and variable-size arrays. Fixed-
Visual
size arrays are declared with the Dim statement, which includes the bounds of the
Basic 6.0 array within this declaration. Dynamic arrays are declared in Dim statements by not
specifying bounds information. The dynamic array then needs to be re-dimensioned
with the ReDim statement before it can be used. In Visual Basic 6.0, the ReDim
statement provides a shorthand way to declare and allocate space for a dynamic array
within a single statement. The ReDim statement is the only statement in Visual Basic
6.0 that can be used both to declare and to initialize a variable.
Visual The ReDim statement is used only for allocating or reallocating the space for an array
Basic.NET rather than reallocating the array. This is because all arrays in Visual Basic.NET are
dynamic, and a Dim statement can be used in Visual Basic.NET both to declare and
to initialize a dynamic array.
Because all variable declarations can both declare and specify an initial value for
variables, the use of ReDim to both declare and initialize variables becomes
redundant and unnecessary. Requiring that only the Dim statement can be used to
declare variables keeps the language simpler and more consistent.
Upgrade If ReDim() is used to declare an array, the appropriate declaration is inserted into the
Wizard code for you. However, the best practice is to insert the Dim statement into the array
first yourself, since using ReDim to declare an array relies on the upgrade tool to
infer the correct declaration. Using ReDim also makes for awkward code, since the
array is being declared identically in two places.

Assignment
Visual There are two forms of assignment: Let assignment (the default) and Set assignment.
Set assignment can be used only to assign object references. The semantics of Let
Basic 6.0 assignment are complex, but can be summarized as follows:

If the expression on the right-hand side of the Let statement evaluates to an
object, the default property of the instance is automatically retrieved and the
result of that call is the value that was assigned.
• If the expression on the left-hand side of the Let statement evaluates to an
object, the default Let property of that object is called with the result of
evaluating the right-hand side. An exception to this rule applies if the left-
hand side is a variant containing an object, in which case the contents of the
variant are overwritten.
Visual There is only one form of assignment. "x = y" means to assign the value of variable
Basic.NET or property "y" to the variable or property "x". The value of an object type variable is
the reference to the object instances, so if "x" and "y" are reference type variables,
then a reference assignment is performed. This single form of assignment reduces
complexity in the language and makes for much more readable code.
Upgrade Set and Let statements are removed. The default properties for strongly typed objects
Wizard are resolved and explicitly added to the code.
See the white paper Preparing Your Visual Basic 6.0 Applications for the Upgrade to
Visual Basic.NET for a full discussion of this topic.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


And, Or, Xor, and Not
And, Or, Xor, and Not operators perform both logical operations and bitwise
Visual
operations, depending on the expressions.
Basic 6.0
Visual And, Or, and Xor apply only to type Boolean. The And operator and Or operator
Basic.NET will short-circuit evaluation if the value of their first operand is sufficient to
determine the result of the operator. The new operators BitOr, BitAnd, and BitXor
are used for bitwise logical operations. The Bitxxx operators do not short-circuit.
This change is necessary to standardize the value of True across all languages, and to
reduce programming errors where it is unclear whether a bitwise or logical operation
is to be applied. Short-circuiting improves performance, since only the necessary
operations of an expression are evaluated.
Upgrade If the And/Or statement is non-Boolean or contains functions, methods, or
Wizard properties, it is upgraded to use a compatibility function with the same behavior as
Visual Basic 6.0. If the And/Or statement is Boolean, and is without side effects, it is
upgraded to use the native Visual Basic.Net statement.
See the white paper Preparing Your Visual Basic 6.0 Applications for the Upgrade to
Visual Basic.NET for a full discussion of this topic.

Operator precedence
Visual The precedence of the logical and bitwise And, Or, Xor, and Not operators is higher
than the precedence of the comparison operators.
Basic 6.0
Visual The precedence of the And, Or, Xor, and Not operators is lower than the precedence
Basic.NET of the comparison operators, so "a > b And a < c" will be evaluated as "(a > b) And (a
< c)". The precedence of the new BitAnd, BitOr, and BitXor operators is higher than
the precedence of the comparison operators, so "a BitAnd &HFFFF <> 0" will be
evaluated as "((a BitAnd &HFFFF) <> 0)".
Since BitAnd, BitOr, and BitNot are operations that return numeric results, their
precedence is higher than that of the relational operators such that the default
precedence allows the result from one of these operators to be compared with another
value.
This results in a more intuitive precedence system than Visual Basic 6.0.
Upgrade This is handled by the Upgrade Wizard. See the white paper Preparing Your Visual
Wizard Basic 6.0 Applications for the Upgrade to Visual Basic.NET for a full discussion of
this topic.

Calling procedures
Two forms of procedure calls are supported: one using the Call statement, which
Visual
requires parentheses around the list of arguments, and one without the Call statement,
Basic 6.0 which requires that parentheses around the argument list not be used.
It is common in Visual Basic 6.0 for a developer to call a procedure without the call
keyword but to attempt to include parentheses around the argument list. Fortunately,
when there is more than one parameter, the compiler will detect this as a syntax error.
However, when only a single parameter is given, the parentheses around the single

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


argument will have the affect of passing an argument variable as ByVal rather than
ByRef. This can result in subtle bugs that are difficult to track down.
Visual Parentheses are now required around argument lists in all cases.
Basic.NET
Upgrade Parentheses are inserted for procedure calls that do no have them.
Wizard

Static procedures
Procedures can be declared with the Static keyword, which indicates that the
Visual
procedure's local variables are preserved between calls.
Basic 6.0
Visual The Static keyword is not supported on the procedure, and all static local variables
Basic.NET need to be explicitly declared with the Static statement.
There is very little need to have all the variables within a procedure be static.
Removing this feature simplifies the language and improves its readability, because
local variables are always stack allocated unless explicitly declared as static.
Upgrade If a procedure is marked as Static, all local variable declarations are changed to
Wizard Static.
Static Sub MySub()
Dim x As Integer
Dim y As Integer
End Sub
Is upgraded to:
Sub MySub()
Static x As Integer
Static y As Integer
End Sub

Parameter ByVal/ByRef default


Visual Parameters that do not specify either ByVal or ByRef default to ByRef.
Basic 6.0
Visual Parameters that do not specify either ByVal or ByRef default to ByVal.
Basic.NET Defaulting to ByVal rather than ByRef eliminates the problem of having a procedure
mistakenly modify a variable passed in by the caller. This also makes the default
calling convention consistent with assignment, such that parameters are effectively
bound to the expressions passed in by an assignment of the expression to the formal
parameter.
Note that to avoid confusion for users moving from Visual Basic 6.0 to Visual
Basic.NET, the IDE will automatically add the ByVal keyword on any parameter
declarations that the user enters without explicitly specifying ByVal or ByRef.
Upgrade ByRef is added to parameters that don't have either a ByVal or ByRef modifier.
Wizard

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


IsMissing and optional parameters
Optional Variant parameters with no default values are initialized to a special error
Visual
code that can be detected by using the IsMissing function.
Basic 6.0
Visual Visual Basic.NET requires that a default value be specified for all optional
Basic.NET parameters. This simplifies the language by reducing the number of special values in
the language.
Upgrade IsMissing functions are replaced with IsNothing functions and are commented with
Wizard an upgrade warning.

ParamArray parameters
Visual When variables are passed to a ParamArray argument, they can be modified by the
called function. ByVal ParamArray elements are not supported.
Basic 6.0
Visual When variables are passed to a ParamArray argument, they cannot be modified by
Basic.NET the called function. ByRef ParamArray elements are not supported.
A more common scenario for ParamArray arguments is for them not to modify
variables that are passed in to them. Not supporting ByRef ParamArray arguments
simplifies the ParamArray calling convention by making ParamArray arguments
be normal arrays. This enables ParamArray arguments to be extended to any
element type and allows functions that expect ParamArray arguments to be called
directly with an array rather than an argument list.
Upgrade Procedures that use ParamArray arguments are commented with an upgrade
Wizard warning. For example, the following code:
Function MyFunction(ParamArray p() As Variant)
'...
End Function
is upgraded to:
' UPGRADE_WARNING: ParamArray p was changed from ByRef to ByVal
Function MyFunction(ByVal ParamArray p() As Object)
'...
End Function

As Any parameters in Declares


Visual A parameter of a native API could be declared "As Any", in which case a call to the
native API could pass in any data type. This was supported to enable calling APIs
Basic 6.0 whose parameters supported two or more data types.
Visual Overloaded Declare statements can be defined so that they allow a native API to be
Basic.NET called with two or more data types. For example, the following Declare statement:
Private Declare Function GetPrivateProfileString _
Lib "kernel32" Alias "GetPrivateProfileStringA" ( _
ByVal lpApplicationName As String, _
ByVal lpKeyName As Any, _
ByVal lpDefault As String, _

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


ByVal lpReturnedString As String, _
ByVal nSize As Integer, _
ByVal lpFileName As String) As Integer
could be replaced with two Declare versions, one that accepts a Integer and one that
accepts a string:
Overloads Private Declare Function GetPrivateProfileStringKey _
Lib "kernel32" Alias "GetPrivateProfileStringA" ( _
ByVal lpApplicationName As String, _
ByVal lpKeyName As String, _
ByVal lpDefault As String, _
ByVal lpReturnedString As String, _
ByVal nSize As Integer, _
ByVal lpFileName As String) As Integer
Overloads Private Declare Function GetPrivateProfileStringNullKey _
Lib "kernel32" Alias "GetPrivateProfileStringA" ( _
ByVal lpApplicationName As String, _
ByVal lpKeyName As Integer, _
ByVal lpDefault As String, _
ByVal lpReturnedString As String, _
ByVal nSize As Integer, _
ByVal lpFileName As String) As Integer
This improves type safety and reduces the chance of a bug causing your program to
fail. This can happen because the compiler will not allow the API to be called with
data types other than those that it is explicitly defined to accept.
Upgrade Declare statements using As Any parameters are commented with an upgrade
Wizard warning.

Implements
Visual The Implements statement specifies an interface or class that will be implemented in
the class module in which it appears.
Basic 6.0 The Visual Basic 6.0 model stems from the fact that COM does not actually allow
classes to have methods; instead, classes are simply a collection of interface
implementations. Visual Basic 6.0 simulates classes with methods by introducing the
concept of a default interface. When an Implements statement specifies a class, that
class implements the default interface of the class. Unfortunately the default interface
concept is not supported in other languages, and any cross-language programming
must deal directly with the default interface.
Visual Implements in Visual Basic.NET is different than in Visual Basic 6.0 in two
Basic.NET essential ways:
1. Classes can not be specified in Implements statements.
2. Every method that implements an interface method requires an Implements
clause at the end of the method declaration statement. This will specify what
interface method it implements.
Visual Basic.NET maintains a strict distinction between interfaces and classes.
Readability is improved by requiring an Implements clause on each method that
implements a method in an interface; it is obvious when reading code that the method
is being used to implement an interface method.
Upgrade If class "a" implements class "b", the interface is declared for class "b", and class "a"
Wizard is changed to implement the interface of class "b":

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Interface _b
Function MyFunction() As String
End Interface
Class a
Implements _b
Function b_MyFunction() As String Implements _b.MyFunction
End Function
End Class

Property
Get, Let, Set
Visual In Visual Basic 6.0, the and property functions for a specific property
can be declared with different levels of accessibility. For example, the Property Get
Basic 6.0 function can be Public while the Property Let is Friend.
Visual The Get and Set functions for a property must both have the same level of
Basic.NET accessibility. This allows Visual Basic.NET to interoperate with other .NET
languages.
Upgrade If there is a different level of accessibility, the new property is public
Wizard

Default properties
Visual Any member can be marked as the default for a class.
Basic 6.0
Visual Only properties that take parameters can be marked as default. It is common for those
Basic.NET properties with parameters to be indexers into a collection.
This makes code more readable, since a reference to an object variable without a
member always refers to the object itself, rather than referring to the object in some
contexts and to the default property value in other contexts. For example, a statement
"Call Display(TextBox1)" might be passing the text box instance to the Display
function or it might be passing the contents of the text box.
Also, removing this ambiguity eliminates the need for a separate statement to perform
reference assignment. An assignment "x = y" always means to assign the contents of
variable "y" to variable "x", rather than to assign the default property of the object
that "y" references to the default property of the object that "x" references.
Upgrade Default properties are resolved where possible. Error comments are added where they
Wizard cannot be resolved (on-late bound objects).

Enumerations
Visual Enumeration constants can be referenced without qualification.
Basic 6.0
Visual Enumerations constants can be referenced without qualification if an Import for the
Basic.NET enumeration is added at file or project level.
This keeps consistency with classes, structures, and interfaces in which members can

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


be given generic names without a risk of conflict with other members. For example,
the Color enumeration and the Fruit enumeration can both contain a constant named
Orange. In Visual Basic 6.0, the convention is to prefix enumeration constants to
make them unique, which leads to awkward names such as MsColorOrange and
MsFruitOrange.
Upgrade References to enumerations are changed to be fully qualified.
Wizard

While
While statements are ended with a WEnd statement.
Visual
Basic 6.0
Visual To be consistent with other block structures, the terminating statement for While is
Basic.NET now End While. This improves language consistency and readability.
Upgrade WEnd statements are changed to End While.
Wizard

On…GoTo and On…GoSub


Visual The On expression Goto destinationlist and On expression GoSub destinationlist
statements branch to one of several specified lines in the destination list, depending
Basic 6.0 on the value of an expression.
Visual On…GoTo and On…GoSub are nonstructured programming constructs. Their use
Basic.NET makes programs harder to read and understand. Select Case can provide a more
structured and flexible way to perform multiple branching.
Note: On Error GoTo is still supported.
Upgrade The following example:
Wizard On MyVariable GoTo 100,200,300
is commented with an upgrade error:
' UPGRADE_ISSUE On MyVariable GoTo was not upgraded
On MyVariable GoTo 100,200,300
You should rewrite your code to avoid such statements. For example:
On x Goto 100,200,300
Can be rewritten as:
Select Case x
Case 1: 'Insert the code for line 100
Case 2: 'Insert the code for line 200
Case 3: 'Insert the code for line 300
End Select

GoSub…Return
The GoSub line … Return statement branches to and returns from a subroutine
Visual
within a procedure.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Basic 6.0
Visual GoSub…Return is a nonstructured programming construct. Its use makes programs
Basic.NET harder to read and understand. Creating separate procedures that you can call may
provide a more structured alternative.
Upgrade As with On...GoTo, these statements are commented with an upgrade error.
Wizard

LSet
LSet pads a string with spaces to make it a specified length, or copies a variable of
Visual
one user-defined type to a variable of a different user-defined type.
Basic 6.0
Visual The LSet statement is not supported. LSet is not type safe, so it can result in errors at
Basic.NET run time. Also, because it is not type safe it requires full trust in order to be executed.
Removing the LSet statement discourages the copying of one structure over another;
however, you can achieve the same effect by modifying your Visual Basic.NET code
to use RtlCopyMemory.
Upgrade This statement:
Wizard LSet a1 = a2
It is commented with an upgrade error
' UPGRADE_ISSUE: LSet cannot assign a UDT from one type to another
LSet a1 = a2

VarPtr, StrPtr, and ObjPtr


Visual VarPtr, StrPtr, and ObjPtr return the addresses of variables as integers, which can
then be passed to API functions that take addresses, such as RtlCopyMemory.
Basic 6.0 VarPtr returns the address of a variable, StrPtr returns the address of a string, and
ObjPtr returns the address of an object. These functions are undocumented.
Visual The addresses of data items can be retrieved, but retrieval must be done via calls into
Basic.NET the CLR. This is because the CLR is normally free to move items within memory, so
it needs to know when not to move the item while the address is being used. The
following example retrieves the address of an object:
Dim MyGCHandle As GCHandle = GCHandle.Alloc(o, GCHandleType.Pinned)
Dim Address As Integer = CInt(MyGCHandle.AddrOfPinnedObject())
'...
MyGCHandle.Free() 'allows the object instance to be moved again
Allowing data items to be moved by the runtime improves the performance of the
runtime.
Upgrade There is no automatic upgrade for these statements, so they are commented with a
Wizard "(statement) is not supported" upgrade error. For example, the following code:
a = VarPtr(b)
is upgraded to:
' UPGRADE_ISSUE: Function VarPtr() is not supported
a = VarPtr(b)
This also causes a compile error.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


File I/O
File I/O statements are included in the language.
Visual
Basic 6.0
Visual File I/O operations are available only through class libraries. Removing the file I/O
Basic.NET statements from the language allows different I/O libraries to be easily used from
Visual Basic.NET. This would be more awkward if the file I/O statements were in the
language, because identifiers such as Open, Close, Print, and Write would be
reserved words.
Upgrade The file I/O statements are upgraded to the corresponding functions. For example, the
Wizard following code:
Open "MyFile.txt" For Input As #1
is upgraded to:
FileOpen( 1, "MyFile.txt", OpenMode.Input )

Debug.Print
Debug.Print outputs a line of text to the Immediate window.
Visual
Basic 6.0
Visual In Visual Studio.NET, the Immediate window is replaced with the Immediate and Output windows.
Basic.NET The Immediate window is used to enter and display results when an application is in break mode. The
Output window shows build information and program output.
Debug.WriteLine outputs a line of text to the Output window. There is also a
Debug.Write method that outputs text to the Output window without a linefeed.
Upgrade Debug.Print is upgraded to Debug.WriteLine.
Wizard

Resource files
Visual Visual Basic 6.0 supports one .res file per project.
Basic 6.0
Visual Visual Basic.NET has rich support for resources. Forms can be bound to retrieve
Basic.NET resources automatically from the new .resX-formatted resource files. Any CLR class
can be stored in a .resX file.
Upgrade Files are upgraded from .res to .resX, and code is changed to load from the .resX
Wizard files.

Windows Applications
Visual Basic forms
Visual Visual Basic 6.0 has its own forms package for creating graphical Windows
applications.
Basic 6.0
Visual Windows Forms is a new forms package for Visual Basic.NET. Because Windows

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Basic.NET Forms is built from the ground up to target the common language runtime (CLR), it
can take advantage of all of its features. In particular, because the Windows Forms
package takes advantage of the deployment, application isolation, versioning, and
code-access security features, you can now build Windows Client applications that
are significantly easier to deploy and update. You can even build Windows Forms
applications that have the same browser deployment characteristics as HTML. These
characteristics, like the granular control of code access security, also make using
Windows Forms controls in the browser very compelling.
The Windows Forms set also offers Visual Basic developers many new features, such
as visual inheritance, improved localization and accessibility support, automatic form
resizing, and an in-place menu editor.
Upgrade Visual Basic forms are upgraded to Windows Forms.
Wizard

PrintForm method
Visual The PrintForm method sends a bit-by-bit image of a Form object to the printer.
However, this printing feature doesn't work correctly on some forms.
Basic 6.0
Visual In Windows Forms, Visual Basic.NET has a printing framework that allows you to
Basic.NET build complex print documents quickly. It also includes a built-in Print Preview
dialog box.
Upgrade PrintForm method calls are commented with an upgrade error. You can use the new
Wizard printing framework to build a print document, or you can even grab a screenshot of
the application window and print it.

Circle, Cls, PSet, Line, and Point methods


Visual The Circle, Cls, PSet, Line, and Point methods allow you to draw graphics on a
form as well as to clear them.
Basic 6.0
Visual Windows Forms has a new set of graphics commands that replace the Form methods
Basic.NET Circle, Cls, PSet, Line, and Point. The Windows Forms package is built on top of
GDI+, a feature-rich 2-D text and imaging graphics library that is now directly
accessible from Visual Basic.NET. Visual Basic programmers have not been able to
access these types of features in previous versions without having to drop down to
Declare statements and GDI APIs. While the learning curve is a little steeper, the
flexibility and power of GDI+ will allow programmers to quickly develop
applications that that would have taken significantly more work in previous versions
of Visual Basic.
Upgrade Calls to these methods are commented with an upgrade error. You can write your
Wizard graphics calls using the GDI+ classes in System.Drawing.

Name property
Visual The Name property returns the name used in code to identify a form, control, or data
access object. It is read-only at run time.
Basic 6.0
Visual Windows Forms does not support the Name property for forms and controls at run

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Basic.NETtime. If you need to iterate the Controls collection to find a control with a certain
name, you can use the .NET Framework System.Reflection classes to find it.
Upgrade Use of the Name property on controls is commented with an upgrade error.
Wizard

Caption property
Visual Some controls, such as Label, have a Caption property that determines the text
displayed in or next to the control. Other controls, such as TextBox, have a Text
Basic 6.0 property that determines the text contained in the control.
Visual In Windows Forms, the property that displays text in a control is consistently called
Basic.NET Text on all controls. This simplifies the use of controls.
Upgrade Caption properties for the controls are changed to Text.
Wizard

Tag property
Visual The Tag property returns or sets an expression that stores any extra data needed for
your program.
Basic 6.0 In Visual Basic 6.0, you need the Tag property because you cannot extend the built-
in controls.
Visual In Windows Forms, you can use inheritance to extend the built-in controls and add
Basic.NET your own properties. Having inheritance available as a tool makes the built-in
controls significantly more flexible. Not only can you add as many properties as you
like, you can also make those properties strongly typed.
Upgrade A Windows Forms extender Tag control in the compatibility library is used to
Wizard provide the same functionality.

ScaleMode property
Visual The ScaleMode property returns or sets a value that indicates the unit of
measurement for coordinates of an object when using graphics methods or when
Basic 6.0 positioning controls.
Visual Windows Forms simplifies form layout by always making measurements in pixels.
Basic.NET In addition, Windows Forms has a better way to handle resizing. The
AutoScaleBaseSize property automatically adjusts the scale according to the
resolution (dpi) of the screen and font size you use.

Upgrade Code that used 'twips' (the default Visual Basic 6.0 ScaleMode setting) upgrades
Wizard perfectly. If ScaleMode is non-twips, you'll have sizing issues.
See the white paper Preparing Your Visual Basic 6.0 Applications for the Upgrade to
Visual Basic.NET for a full discussion of this topic.

Fonts
Visual Forms and controls can use any Windows font.
Basic 6.0
Visual Forms and controls can only use TrueType or OpenType fonts. These types of fonts
Basic.NET solve many inconsistencies across different operating-system versions and their

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


localized versions. These fonts also provide features, such as device resolution
independence and anti-aliasing.
Upgrade If you have non-TrueType fonts in your application, these are changed to the default
Wizard Windows Form font; however, formatting (size, bold, italic, underline) will be lost.

Screen.MousePointer property
Visual The MousePointer property on the Screen object returns or sets a value indicating
the type of mouse pointer displayed when the mouse is outside your application's
Basic 6.0 forms at run time.
Visual The mouse pointer can be manipulated for forms inside of the application, but it
Basic.NET cannot when it's outside of the application. We will be addressing this feature in a
future release.
Upgrade Use of Sceen.MousePointer is commented with an upgrade error.
Wizard

Timer.Interval property
Visual The Interval property on a Timer control returns or sets the number of milliseconds
between calls to the Timer event. If it's set to 0, it disables the Timer control. The
Basic 6.0 Enabled property also determines whether the timer is running. This is confusing,
because even when the Enabled propertyis true, the timer won't be enabled if the
interval is 0.
Visual The Interval property indicates the time, in milliseconds, between timer ticks. This
Basic.NET property cannot be set to 0. The Enabled property indicates whether the timer is
running. This provides a more intuitive behavior to simplify coding with Timer
objects.
Upgrade Where the Upgrade Wizard can detect that Timer.Interval is set to 0, it will be
Wizard commented with an upgrade error.
You are advised to use Timer.Enabled in your Visual Basic 6.0 applications, as this
upgrades perfectly.

Control arrays
Visual A control array is a group of controls that share the same name and type. They also
share the same event procedures. A control array has at least one element and can
Basic 6.0 grow to as many elements as your system resources and memory permit. Elements of
the same control array have their own property settings.
Visual The Windows Form architecture natively handles many of the scenarios for which
Basic.NET control arrays were used. For instance, in Windows Forms you can handle more than
one event on more than one control with a single event handler.
Upgrade A Control Array Windows Forms extender control in the compatibility library
Wizard provides this feature.

Menu controls
Visual A Menu control represents each item in a menu tree. The same Menu control
instance can be used simultaneously as a main menu or a context menu.
Basic 6.0
Visual A MenuItem control represents each item in a menu tree. The MenuItem control can

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Basic.NETbe added to either a MainMenu item or a ContextMenu item, but not to both at
once. You can use the CloneMenu method on the MenuItem to create a copy if
you'd like to share a menu between a MainMenu object and a ContextMenu object.
Upgrade Use of context menus is commented with an upgrade error. You can use
Wizard MenuItem.CloneMenu to make a copy of the MainMenu item for use as a
ContextMenu item.

OLE container control


The OLE container control enables you to add OLE objects to your forms.
Visual
Basic 6.0
Visual There is no OLE container control in Visual Basic.NET. If you need the equivalent of
Basic.NET the OLE container control, you can add the WebBrowser control to a form and use it
as an OLE container control.
Upgrade An error is added in the upgrade report, and an unsupported-control placeholder is put
Wizard on the form.

Image control
Visual The Image and PictureBox controls both display a graphic from a bitmap, icon,
metafile, enhanced metafile, JPEG, or GIF file.
Basic 6.0
Visual The Visual Basic.NET PictureBox control replaces the Visual Basic 6.0 PictureBox
Basic.NET and Image controls. The Windows Forms PictureBox control also supports animated
GIFs. However, if you require a very lightweight solution for painting an image onto
a form, you can also override the OnPaint event for the form and use the
DrawImage method.
Upgrade Image controls are changed to PictureBox controls.
Wizard

Line and Shape controls


The Line control displays as a horizontal, vertical, or diagonal line. The Shape control
Visual
displays a rectangle, square, oval, circle, rounded rectangle, or rounded square.
Basic 6.0
Visual The GDI+ classes in System.Drawing replace the Line and Shape controls. If you
Basic.NET want to draw shapes on the form, override the OnPaint event and paint circles,
squares, and so forth by using the GDI+ Draw methods.
Upgrade Horizontal and vertical Line controls are changed to Label controls (no text, with
Wizard height or width set to 1). Diagonal lines raise an error in the report, and an
unsupported-control placeholder is put on the form.
Rectangle and square Shape controls are changed to Label controls. Other Shape
controls raise an error in the report, and an unsupported-control placeholder is put on
the form.

Windowless controls
Lightweight controls, sometimes referred to as windowless controls, differ from
Visual
regular controls in one significant way: They don't have a window handle (hWnd

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Basic 6.0 property). Because of this, they use fewer system resources. You create a lightweight
user control by setting the Windowless property to true at design time. Lightweight
user controls can contain only other lightweight controls. Not all containers support
lightweight controls.
Visual Most windowless controls will default to being windowed when used in Windows
Basic.NET Forms. The main benefit of using windowless controls is to reduce resource
consumption (window handles) when you have a very large number of controls on a
form. This applies to Windows 9x only. Windows NT and Windows 2000 do not
have these resource constraints.
While there are disadvantages to using windowless controls (layout issues such as
layering problems), Microsoft recognizes the value of them and will be releasing
samples that show how to achieve similar effects in Windows Forms.
Upgrade No special action is required.
Wizard

Clipboard
Visual The Clipboard object provides access to the system clipboard.
Basic 6.0
Visual The Clipboard class provides methods to place data on and retrieve data from the
Basic.NET system clipboard. The new Clipboard class offers more functionality and supports
more clipboard formats than the Visual Basic 6.0 Clipboard object. The object
model has been restructured to support these.
Upgrade The existing clipboard code cannot automatically be upgraded because of the
Wizard differences between object models. Clipboard statements will be commented with an
upgrade error.

Dynamic data exchange


Certain controls have properties and methods that support Dynamic Data Exchange
Visual
(DDE) conversations.
Basic 6.0
Visual Windows Forms has no built-in DDE support.
Basic.NET
Upgrade DDE properties and methods are commented with an upgrade warning.
Wizard

Web Applications
WebClasses
Visual A WebClass is a Visual Basic component that resides on a Web server and responds
to input from the browser. A WebClass typically contains WebItems that it uses to
Basic 6.0 provide content to the browser and expose events.
Visual Web Forms is a .NET Framework feature that you can use to create a browser-based
Basic.NET user interface for your Web applications. Visual Basic.NET has a WYSIWYG
designer for graphical Web Form creation using controls from the Toolbox. This

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


gives Web user-interface development the same feel as Windows development. Also,
when the project is built, the Internet Information Services (IIS) server does not have
to be stopped and restarted to deploy the new bits, as it does with WebClasses.
Upgrade WebClasses are upgraded to Web Forms. Any state storage calls will be commented
Wizard with an upgrade warning. These can be rewritten to take advantage of the ASP.NET
state management features.
You may also choose to leave WebClass applications in Visual Basic 6.0, and
navigate from a Visual Basic.NET Web Form to a WebClass, to a WebForm, and so
on..

ActiveX documents and DHTML applications


Visual ActiveX® documents can appear within Internet browser windows, and offer built-in
viewport scrolling, hyperlinks, and menu negotiation. DHTML applications contain
Basic 6.0 DHTML pages and client-side ActiveX DLLs.
Visual Web Forms support broad-reach applications through standard HTML. Rich
Basic.NET applications can be supported in a much more secure way by using Windows Forms
controls hosted in a browser, or with a downloaded "safe Windows Form" EXE. This
code runs inside of a secure sandbox, so that it cannot do harm to a user's computer.
Upgrade While ActiveX documents and DHTML applications cannot be directly upgraded,
Wizard you can still navigate between ActiveX documents, DHTML applications, and Web
Forms.

Data
ADO, RDO, and DAO code
Visual ADO, RDO, and DAO objects are used for connected and disconnected data access.
Basic 6.0
Visual ADO.NET provides additional classes for disconnected data access. These classes
Basic.NET provide performance and scalability improvements over previous versions of
ActiveX® Data Objects (ADO) when used in distributed applications. They also
allow simpler integration of XML data with your database data.
Upgrade ADO, RDO, and DAO can still be used in Visual Basic.NET code.

ADO, RDO, and DAO Data Binding


Controls on Visual Basic forms can be bound to ADO, RDO, and DAO data sources.
Visual
Basic 6.0
Visual ADO.NET offers read/write data binding to controls for Windows Forms and read-
Basic.NET only data binding for Web Forms.
Upgrade ADO data binding is upgraded to the new ADO.NET data binding. However, RDO
Wizard and DAO data binding cannot be upgraded and will add errors to the upgrade report.

Integrated Development Environment

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Immediate window
From the Immediate window in Design mode, you can run parts of your code without
Visual
launching the entire application through its Startup object. For example, you can
Basic 6.0 show forms, call module procedures, and interact with global variables. This is
possible because Visual Basic 6.0 is running the application from an in-memory
image of the code, and is not debugging the built output that's used at run time.
Visual From the Command window in Design mode, you can execute IDE commands, but
Basic.NET you cannot run individual parts of your application. This is because Visual
Basic.NET runs and debugs the actual built output that is used at run time. This form
of debugging provides the most accurate replication of the run-time behavior.

IDE and project extensibility


The Visual Basic 6.0 integrated development environment (IDE) extensibility model
Visual
is supported by Visual Basic 6.0 only.
Basic 6.0
Visual The new IDE extensibility model is generic for all project types inside of Visual
Basic.NET Studio.NET. This makes it much simpler to create add-ins that work with many
different types of projects. The Visual Basic project system extensibility model is
also shared with C#--so project specific functions, such as adding a reference or
changing a project property, are done the same way in both languages.
A Visual Studio.NET code model also gives extensibility writers a common object
model to walk the code in projects of different languages. Visual Basic supports
reading code through the code model. To write code, you can grab an insert point
from the model and then spit out Visual Basic syntax.

10 Syntax Changes in VB.NET Beta 2


The long-awaited VB.NET Beta 2 has been released at last, so this week's column is devoted to a few of
the many changes in syntax that this new version enforces. This isn't a complete list, of course, and I am
pretty sure I am leaving out something important, but at least you can use this information to get familiar
with the new beta in less time.
1) BitAnd, BitOr, BitXor, and BitNot are gone
Beta 1 used these operators to implement bit-wise operations, whereas the old And, Or, Xor, and Not, had
become pure Boolean operators. After many complains from the VB community, they decided to restore
things as they work in VB6: And, Or, Xor, and Not are again bit-wise operators, and the Bitxxx operators
are gone.

2) The AndAlso and OrElse operators


These operators implement short-circuit evaluation in If and Do expressions (and in general, in all Boolean
expressions that consist of multiple Boolean items). Consider this expression:
If x > 0 AndAlso y ^ x < 1 Then 26
In this case VB doesn't evaluate the term (y ^ x) if (x > 0) happens to be False, because that wouldn't
change the value of the expression. Similarly, in the following case
Do While x = 0 OrElse y ^ 3 < x

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


VB stops evaluating the expression if (x = 0) is True, because the entire expression is surely True. While I
don't like the new AndAlso and OrElse, I think that these new names prevent VB developers from
carelessly applying short-circuiting when they don't really mean to do so. Maybe the language is less
elegant, but certainly there will be fewer mistakes when converting legacy VB6 code.

3) Value in DIM and REDIM is the UBound of the array


In Beta 1, the value passed to Dim and ReDim was the number of elements (as in C++ and C#), a detail that
puzzled many die-hard VBers. In Beta 2 this value has the same meaning as under VB6. Because all
VB.NET arrays are zero-based, it means that the array always has one more element than the number
specified in the statement:
Dim arr(10) As Integer ' this array has 11 elements
4) Equality must be performed with the Is operator
In Beta 1 you can check whether two object variables point to the same object instance using the =
operator; in Beta 2 and the final version you must use the Is operator (as you do in VB6).

5) The Microsoft.VisualBasic.Compatibility.VB6 namespace has moved


This namespace contained all the functions that have a VB6 name, and was meant to assist VB developers
in migrating their apps. In Beta 2 all these functions are in the less verbose Microsoft.VisualBasic
namespace. If you have written VB.NET code that uses these functions, you should only modify the
Imports statement.

6) Attributes now precede the item they refer to


In Beta 1, position of < > attributes preceded the _name_ of the item they refer to, which led to a rather
weird syntax, as in:
Class <Description("Sample Class")> MyClass
Fortunately, in Beta 2 and the final release, attributes will precede the item they refer to, making for a more
readable syntax that is similar to C#'s:
<Description("Sample Class")> Class MyClass
You can move the attribute to a line of its own for a syntax that resembles C# even more closely:
<Description("Sample Class")> _ Class MyClass
7) The Currency data type is gone
This data type isn't supported any longer and you should use Decimal instead. The Decimal type has a
higher precision and larger valid range.

8) The ToString method is now locale-aware


All classes inherit the ToString method from System.Object (the mother of all objects in .NET), and usually
override it so that it returns a textual representation of the object's value. For all the objects in the .NET
framework, ToString returns a local-aware value now. For example, if the object has a numeric value,
ToString will return the string representation of such a value, but will use different symbols for the decimal
separator: a period in the US, a comma in most European countries.

9) Names of collection objects have changed


This change affects the name of many objects in the framework. In Beta 1 the convention for naming
collection-like objects was to use the plural of the name (e.g. "Parameters", "Properties", etc.). In Beta 2 the
convention has changed, and now these objects have a trailing "Collection" word (e.g.
"ParameterCollection", "PropertyCollection"). You should use a similar naming convention in your own
object hierarchies.

10) ADO.NET namespaces have changed


In Beta 1, ADO.NET had two important namespaces: System.Data.ADO for objects of the generic data
provider, and System.Data.Sql for the more specific SQL Server provider. These namespaces have changed
into System.Data.OleDb and System.Data.SqlClient, respectively.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Preparing Your Visual Basic 6.0 Applications for the Upgrade to Visual
Basic.NET
Microsoft Corporation

October 2000

Summary: This document provides recommendations for Microsoft Visual Basic developers planning to upgrade their applications to
Visual Basic.NET. It includes information on the Visual Basic.NET Upgrade Tool and discusses architectural guidelines for enabling
a smooth upgrade from Visual Basic 6 to Visual Basic.NET. (26 printed pages)

Contents
Overview
What Is Visual Basic.NET?
Why Is Visual Basic.NET Not 100% Compatible?
Upgrading to Visual Basic.NET
Working with Both Visual Basic 6.0 and Visual Basic.NET
Architecture Recommendations
Browser-based Applications
Client/Server Projects
Single-tier Applications
Data
Upgrading
Variant to Object
Integer to Short
Property Syntax
Visual Basic Forms to Windows Forms
Interfaces
Upgrade Report and Comments
Programming Recommendations
Use Early-Binding
Use Date for Storing Dates
Resolve Parameterless Default Properties
Avoid Null Propagation
Use Zero Bound Arrays
Use Constants Instead of Underlying Values
Arrays and Fixed-Length Strings in User-Defined Types
Avoid Legacy Features
Windows APIs
Considerations for Forms and Controls

Overview
This document provides recommendations for developers using Microsoft® Visual Basic® who are planning to upgrade their
applications to Microsoft Visual Basic.NET.

Visual Basic.NET will open and upgrade Visual Basic 6.0 projects to Visual Basic.NET technologies, but in most cases you will need
to make some modifications to your projects after bringing them into Visual Basic.NET. The purpose of this document is to
recommend how to design and implement your current Visual Basic projects to minimize the number of changes you will need to
make when they are upgraded to Visual Basic.NET. Where appropriate, we use new language constructs; however, this document is
not intended to be a Visual Basic.NET language reference.

Note Visual Basic.NET is still in development; some compatibility details may change before the product is
released. Following the guidelines in this document does not guarantee your code will not require changes;
instead the guidelines aim to reduce the amount of work needed for conversion.

The upgrade wizard and command-line upgrade tools in Visual Basic.NET are still in an early stage of
development and, as such, their functionality is limited. The purpose of including them in the Beta release is to
give you a feel for how the upgrade process will work and to see how VB 6.0 code is modified to work in
VB.NET; in Beta1, most real-world projects probably cannot be migrated successfully.

What Is Visual Basic.NET?

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Visual Basic.NET is the next version of Visual Basic. Rather than simply adding some new features to Visual Basic 6.0, Microsoft has
reengineered the product to make it easier than ever before to write distributed applications such as Web and enterprise n-tier systems.
Visual Basic.NET has two new forms packages (Windows Forms and Web Forms); a new version of ADO for accessing disconnected
data sources; and streamlined language, removing legacy keywords, improving type safety, and exposing low-level constructs that
advanced developers require.

These new features open new doors for the Visual Basic developer: With Web Forms and ADO.NET, you can now rapidly develop
scalable Web sites; with inheritance, the language now truly supports object-oriented programming; Windows Forms natively supports
accessibility and visual inheritance; and deploying your applications is now as simple as copying your executables and components
from directory to directory.

Visual Basic.NET is now fully integrated with the other Microsoft Visual Studio.NET languages. Not only can you develop
application components in different programming languages, your classes can now inherit from classes written in other languages
using cross-language inheritance. With the unified debugger, you can now debug multiple language applications, irrespective of
whether they are running locally or on remote computers. Finally, whatever language you use, the Microsoft .NET Framework
provides a rich set of APIs for Microsoft Windows® and the Internet.

Why Is Visual Basic.NET Not 100% Compatible?


There were two options to consider when designing Visual Basic.NET—retrofit the existing code base to run on top of the .NET
Framework, or build from the ground up, taking full advantage of the platform. To deliver the features most requested by customers
(for example, inheritance, threading), to provide full and uninhibited access to the platform, and to ensure that Visual Basic moves
forward into the next generation of Web applications, the right decision was to build from the ground up on the new platform.

For example, many of the new features found in Windows Forms could have been added to the existing code base as new controls or
more properties. However, this would have been at the cost of all the other great features inherent to Windows Forms, such as security
and visual inheritance.

One of our major goals was to ensure Visual Basic code could fully interoperate with code written in other languages, such as
Microsoft Visual C#™ or Microsoft Visual C++®, and enable the Visual Basic developer to harness the power of the .NET
Framework simply, without resorting to the programming workarounds traditionally required to make Windows APIs work. Visual
Basic now has the same variable types, arrays, user-defined types, classes, and interfaces as Visual C++ and any other language that
targets the Common Language Runtime; however, we had to remove some features, such as fixed-length strings and non-zero based
arrays from the language.

Visual Basic is now a true object-oriented language; some unintuitive and inconsistent features like GoSub/Return and DefInt have
been removed from the language.

The result is a re-energized Visual Basic, which will continue to be the most productive tool for creating Windows-based applications,
and is now positioned to be the best tool for creating the next generation Web sites.

Upgrading to Visual Basic.NET


Visual Basic.NET enables a fundamental shift from traditional Windows development to building next-generation Web and n-tier
applications. For this reason, your code will need to be upgraded to take advantage of Visual Basic.NET.

This happens automatically when you open a Visual Basic 6.0 project in Visual Basic.NET: the Upgrade Wizard steps you through the
upgrade process and creates a new Visual Basic.NET project (your existing project is left unchanged). This is a one-way process; the
new Visual Basic.NET project cannot be opened in Visual Basic 6.0.

When your project is upgraded, the language is modified for any syntax changes and your Visual Basic 6.0 Forms are converted to
Windows Forms. In most cases, you will have to make some changes to your code after it is upgraded. This is required because certain
objects and language features either have no equivalent in Visual Basic.NET, or have an equivalent too dissimilar for an automatic
upgrade. After the upgrade, you may also want to change your application to take advantage of some of the new features in Visual
Basic.NET.

For example, Windows Forms supports control anchoring, so you can remove most of your old Visual Basic 6.0 Form resize code:

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Figure 1. VB.NET support for control anchoring

To help you make the changes, after your project is upgraded, Visual Basic.NET adds an ‘upgrade report’ to your project itemizing
any problems, and inserts comments into your upgraded code alerting you to statements that will need to be changed. Because these
comments are displayed as ‘TO DO’ tasks in the new Task List window, you can easily see what changes are required, and navigate to
the code statement simply by double-clicking the task. Each task and item in the upgrade report is associated with an online Help topic
giving further guidance as to why the code needs to be changed, and what you need to do.

By following the recommendations in this document, you can minimize and, in some cases, eliminate the changes needed after
upgrading your project to Visual Basic.NET. In most cases, the recommendations simply represent good programming practices;
however, we also identify the objects and methods which have no equivalents, and which should be used sparingly if you intend to
upgrade your project to Visual Basic.NET.

Working with Both Visual Basic 6.0 and Visual Basic.NET


Visual Basic.NET supports upgrading Visual Basic 6.0 projects; if you have a project written in Visual Basic versions 1 to 5, we
recommend you load it into VB6 (choosing to upgrade Microsoft ActiveX® controls), compile, and save the project before upgrading
it to Visual Basic.NET.

Both Visual Basic.NET and Visual Basic 6.0 can be installed on the same computer and run at the same time. Likewise, applications
written in Visual Basic.NET and Visual Basic 6.0 can be installed and executed on the same computer. Components written in Visual
Basic.NET can interoperate with COM components written in earlier versions of Visual Basic and other languages. For example, you
can drop an ActiveX control written in Visual Basic 6.0 onto a Visual Basic.NET Windows Form, use a Visual Basic 6.0 COM object
from a Visual Basic.NET class library, or add a reference to a Visual Basic.NET library to a Visual Basic 6.0 executable.

Components compiled with Visual Basic.NET have subtle run-time differences from components compiled with Visual Basic 6.0. For
starters, because Visual Basic.NET objects are released through garbage collection, when objects are explicitly destroyed, there may
be a lag before they are actually removed from memory. There are additional differences such as the variant/object changes described
later in this document. The combined result of these differences is that Visual Basic.NET applications will have similar but not
identical run-time behavior to Visual Basic 6.0 applications.

In addition, Visual Basic.NET makes binary compatibility between Visual Basic.NET components and those in Visual Basic 6.0
unnecessary. Components now have a more robust versioning and deployment system than ever before, files can be deployed by
simply copying to a directory (no more RegSvr32), and upgrading to a new version of a component is as simple as replacing the old
file with a new file. All you have to do is ensure classes and methods are compatible with the previous version.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Architecture Recommendations
The .NET platform improves upon previous architectures, and adds greater support for scalability and distributed applications though
disconnected data access, HTTP-based message transport, and file-copy based deployment (no more registering of components). To
best take advantage of these features, you should design your applications with an architecture similar to that you would use in Visual
Basic.NET.

Browser-based Applications

Visual Basic 6.0 and Microsoft Visual Studio® 6.0 offered several technologies for creating browser-based Internet and intranet
applications:

• Webclasses

• DHTML projects

• ActiveX documents

• Active Server Pages (ASP)

Visual Basic.NET introduces ASP.NET, an enhanced version of ASP, and adds to the architecture with Web Forms, which are HTML
pages with Visual Basic events. The architecture is server-based.

Below is a list of recommendations and architectural suggestions for developing Visual Basic 6.0 browser-based applications that will
most seamlessly migrate to Visual Basic.NET projects:

• We recommend you use the Microsoft multi-tier architecture guidelines (see Building Solutions Today With Microsoft's

Web Solution Platform)to create your applications, create the interface with ASP, and use Visual Basic 6.0 or Visual C++ 6.0

COM objects for your business logic. ASP is fully supported in Visual Basic.NET, and you can continue to extend your

application using ASP, ASP.NET, and Web Forms. The Visual Basic 6.0 and Visual C++ 6.0 business objects can either be used

without modification or upgraded to Visual Studio.NET.

• DHTML applications contain DHTML pages and client-side DLLs. These applications cannot be automatically upgraded

to Visual Basic.NET. We recommend you leave these applications in Visual Basic 6.0.

• ActiveX documents are not supported in Visual Basic.NET, and like DHTML projects, cannot be automatically upgraded.

We recommend you either leave your ActiveX document applications in Visual Basic 6.0 or, where possible, replace ActiveX

documents with user controls.

• Visual Basic 6.0 ActiveX documents and DHTML applications can interoperate with Visual Basic.NET technologies. For

example, you can navigate from a Visual Basic.NET Web Form to a Visual Basic 6.0 DHTML page, and vice–versa.

• Webclasses no longer exist in Visual Basic.NET. Webclass applications will be upgraded to ASP.NET; however, you will

have to make some modifications after upgrading. Existing Webclass applications can interoperate with Visual Basic.NET Web

Forms and ASP applications, but for new projects we recommend you use the Windows DNA platform of ASP with Visual

Basic 6.0 business objects.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


For more information about building applications with the Microsoft multi-tier architecture, see the Microsoft Windows DNA Web
site.

Client/Server Projects

Visual Basic 6.0 offered several technologies for creating client/server applications:

• Visual Basic Forms

• Microsoft Transaction Server (MTS)/COM+ middle-tier objects

• User controls

In Visual Basic.NET, there is a new form package: Windows Forms. Windows Forms has a different object model than Visual Basic
6.0 Forms, but is largely compatible. When your project is upgraded, Visual Basic Forms are converted to Windows Forms.

Visual Basic.NET improves support for developing middle-tier MTS and COM+ component services components. Using the unified
debugger, you can step from a client application into an MTS/COM+ component and back to the client. You can also use the unified
debugger to step through Visual Basic 6.0 MTS/COM+ components (providing they are compiled to native code, with symbolic debug
information and no optimizations).

Visual Basic.NET also introduces a new middle-tier component, Web Services. Web Services are hosted by ASP.NET, and use the
HTTP transport allowing method requests to pass through firewalls. They pass and return data using industry standard XML, allowing
other languages and other platforms to access their functionality. Although they do not support MTS transactions, you may want to
change your MTS/COM+ components to Web Services in cases where you do not need distributed transactions but still want to
interoperate with other platforms. Although there is no automatic method for this, the task is trivial and can be completed in minutes
using a drag-and-drop operation after your project has been upgraded to Visual Basic.NET.

When your project is upgraded, user controls are upgraded to Windows controls; however, custom property tag settings and
accelerator keys assignments will not be upgraded.

Single-tier Applications

Visual Basic 6.0 supported building several types of single-tier applications:

• Single-tier database applications

• Visual Basic add-ins

• Utility programs and games

Single-tier database applications are typified by a Visual Basic application storing data in an Microsoft Access database. These
applications will upgrade to Visual Basic.NET with some limitations (see the Data section later in this document).

Now that the Visual Basic.NET IDE is a fully integrated part of the Visual Studio.NET IDE, Visual Basic.NET has a new language-
neutral extensibility model. Visual Basic.NET add-ins are now Visual Studio.NET add-ins, and you can automate and add features to
any language in Visual Studio.NET. For example, you can write a Visual Basic.NET add-in that re-colors a Visual C# Windows Form
or adds comments to a Visual Basic class. In order to provide this functionality, Visual Basic.NET has moved away from the old
extensibility model, and you will need to change the extensibility objects in your application to take advantage of the new features.

Many applications fall under the category of Utility programs. Utility applications that manipulate files, registry settings, and the like
will often upgrade without requiring any additional changes. After upgrading, there are many new features you can take advantage of,
such as exception handling in the language to capture file system errors, and using .NET Framework registry classes to manipulate the
registry. One thing to be aware of is that applications relying on specific performance characteristics of Visual Basic 6.0, such as
arcade games, will probably require some modifications because Visual Basic.NET has different performance characteristics. For
games support in Visual Basic.NET, you can use Microsoft DirectX® 7, or the new version of GDI. GDI+ introduces many new
features, including Alpha blending support for all 2-D graphics primitives, anti-aliasing, and expanded support for image file formats.

Data

Visual Basic 6.0 offered several types of data access:

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


• ActiveX Data Objects (ADO)

• Remote Data Objects (RDO)

• Data Access Objects (DAO)

Visual Basic.NET introduces an enhanced version of ADO called ADO.NET. ADO.NET targets disconnected data, and provides
performance improvements over ADO when used in distributed applications. ADO.NET offers read/write data binding to controls for
Windows Forms and read-only data binding for Web Forms.

DAO, RDO, and ADO can still be used in code from Visual Basic.NET, with some trivial modifications (covered in the language
section of this document). However, Visual Basic.NET does not support DAO and RDO data binding to controls, data controls, or
RDO User connection. We recommend that if your applications contain DAO or RDO data binding you either leave them in Visual
Basic 6.0 or upgrade the DAO and RDO data binding to ADO before upgrading your project to Visual Basic.NET, as ADO data
binding is supported in Windows Forms. Information on how to do this is available in the Visual Basic 6.0 Help.

In summary, we recommend using ADO in your Visual Basic 6.0 projects.

Upgrading
When your code is upgraded, Visual Basic.NET creates a new upgraded project and makes most of the required language and object
changes for you. The following sections provide a few examples of how your code is upgraded.

Variant to Object

Previous versions of Visual Basic supported the Variant datatype, which could be assigned to any primitive type (except fixed-length
strings), Empty, Error, Nothing and Null. In Visual Basic.NET, the functionality of the Variant and Object datatypes is combined
into one new datatype: Object. The Object datatype can be assigned to primitive datatypes, Empty, Nothing, Null, and as a pointer to
an object.

When your project is upgraded to Visual Basic.NET, all variables declared as Variant are changed to Object. Also, when code is
inserted into the editor, the Variant keyword is replaced with Object.

Integer to Short

In Visual Basic.NET, the datatype for 16-bit whole numbers is now Short, and the datatype for 32-bit whole numbers is now Integer
(Long is now 64 bits). When your project is upgraded, the variable types are changed:
Dim x As Integer
dim y as Long
is upgraded to:
Dim x As Short
dim y as Integer
Property Syntax

Visual Basic.NET introduces a more intuitive syntax for properties, which groups Get and Set together. Your property statements are
upgraded as shown in the following example:
Property Get MyProperty() As Integer
MyProperty = m_MyProperty
End Property
Property Let MyProperty(NewValue As Integer)
m_MyProperty = NewValue
End Property
is upgraded to:
Property MyProperty() As Short
Get
MyProperty = m_MyProperty
End Get

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Set
m_MyProperty = Value
End Set
End Property
Visual Basic Forms to Windows Forms

Visual Basic.NET has a new forms package, Windows Forms, which has native support for accessibility and has an in-place menu
editor. Your existing Visual Basic Forms are upgraded to Windows Forms.

Figure 2. Windows Forms in-place menu editor. (Click figure to see larger image.)

Interfaces

In previous versions of Visual Basic, interfaces for public classes were always hidden from the user. In Visual Basic.NET, they can be
viewed and edited in the Code Editor. When your project is upgraded, you choose whether to have interface declarations automatically
created for your public classes.

Upgrade Report and Comments

After your project is upgraded, an upgrade report is added to your project, itemizing any changes you will need to make to your
upgraded code. Additionally, comments are added to your code to alert you to any potential problems. These comments show up
automatically in the Visual Studio.NET Task List.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Figure 3. Upgrade comments are added to Visual Basic code as well as the Task List. (Click figure to see larger image.)

Programming Recommendations
This section provides recommendations for how you should write code to minimize the changes you will need to make after upgrading
your project to Visual Basic.NET.

Use Early-Binding

Both Visual Basic 6.0 and Visual Basic.NET support late-bound objects, which is the practice of declaring a variable as the Object
datatype and assigning it to an instance of a class at run time. However, during the upgrade process, late-bound objects can introduce
problems when resolving default properties, or in cases where the underlying object model has changed and properties, methods, and
events need to be converted. For example, suppose you have a Form called Form1 with a label called Label1; the following Visual
Basic 6.0 code would set the caption of the label to “SomeText”:
Dim o As Object
Set o = Me.Label1
o.Caption = "SomeText"
In Visual Basic.NET Windows Forms, the Caption property of a label control is now called Text. When your code is upgraded, all
instances of the Caption property are changed to Text, but because a late-bound object is type-less, Visual Basic cannot detect what
type of object it is, or if any properties should be translated. In such cases, you will need to change the code yourself after upgrading.

If you rewrite the code using early-bound objects, it will be upgraded automatically:
Dim o As Label
Set o = Me.Label1
o.Caption = "SomeText"
Where possible you should declare variables of the appropriate object type rather than simply declaring them as the Object datatype.

In the cases where you do use Object and Variant variables in your Visual Basic 6.0 code, we recommend you use explicit conversions
when you assign the variables, perform operations on the variables, or pass the variables to a function. For example, the intention of
the ‘+’ operation in the following code is unclear:

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Dim Var1 As Variant
Dim Var2 As Variant
Dim Var3 As Variant
Var1 = "3"
Var2 = 4
Var3 = Var1 + Var2 'UNCLEAR: What is the intention?
Should Var1 and Var2 be added as strings or integers?

The above example may result in a run-time error in Visual Basic.NET. Rewriting the final line to use explicit conversions ensures the
code will work:
Var3 = CInt(Var1) + CInt(Var2) 'GOOD: explicit conversion
Visual Basic.NET supports overloading functions based on parameter type. For example, the Environ function now has two forms:

Environ( Expression As Integer) As String


Environ( Expression As String ) As String
Visual Basic.NET determines which function to call based on the parameter type. If you pass an integer to Environ(), the integer
version is called; if you pass a string, then the string version is called. Code that passes a Variant or Object datatype to an overloaded
function may cause a compile or runtime error. Using an explicit conversion, as in the following example, will mean your code will
work as intended after it is upgraded to Visual Basic.NET:
Dim a As String
Dim v As Variant
v = "Path"
a = Environ(CStr(v)) 'GOOD: explicit conversion
Using explicit conversions of late bound objects is good coding practice. It makes the intention of the code easy to determine, and
makes it easier for you to move your project to Visual Basic.NET.

Use Date for Storing Dates

Earlier versions of Visual Basic supported using the Double datatype to store and manipulate dates. You should not do this in Visual
Basic.NET, because dates are not internally stored as doubles. For example, the following is valid in Visual Basic 6.0, but may cause a
compile error in Visual Basic.NET:
Dim dbl As Double
Dim dat As Date
dat = Now
dbl = dat 'VB.NET: Double can't be assigned to a date
dbl = DateAdd("d", 1, dbl) 'VB.NET: Can't use Double in date functions
dat = CDate(dbl) 'VB.NET: CDate can't convert double to date
The .NET framework provides the ToOADate and FromOADate functions to convert between doubles and dates. However, when
your project is upgraded to Visual Basic.NET, it is difficult to determine the intention of code that uses doubles to store dates. To
avoid unnecessary modifications to your code in Visual Basic.NET, always use the Date datatype to store dates.

Resolve Parameterless Default Properties

In Visual Basic 6.0, many objects expose default properties, which can be omitted as a programming shortcut. For example, TextBox
has a default property of Text, so instead of writing:
MsgBox Form1.Text1.Text
you use the shortcut:

MsgBox Form1.Text1
The default property is resolved when the code is compiled. In addition, you could also use default properties with late-bound objects,
as in the following example:
Dim obj As Object
Set obj = Form1.Text1
MsgBox obj
In the late-bound example, the default property is resolved at run time, and the MsgBox displays the value of the default property of
the TextBox as Text1.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Visual Basic.NET does not support parameterless default properties, and consequently does not allow this programming shortcut.
When your project is upgraded, Visual Basic.NET resolves the parameterless default properties, but late-bound usages that rely on
run-time resolution cannot be automatically resolved. In these cases, you will have to change the code yourself. An additional
complication is that many libraries implement default properties using a property called _Default. _Default acts as a proxy, passing
calls to the real default property. So, when your project is upgraded, some default properties will be resolved to _Default. The code
will still work as usual, but it will be less understandable than code written explicitly using the actual property. For these reasons, try
to avoid using parameterless default properties in your Visual Basic 6.0 code. Instead of writing:
Dim obj As Object
Set obj = Me.Text1
MsgBox obj 'Relying on default property
MsgBox Me.Text1 'Relying on default property
use:
Dim obj As Object
Set obj = Me.Text1
MsgBox obj.Text 'GOOD: Default property is resolved
MsgBox Me.Text1.Text 'GOOD: Default property is resolved
While parameterless default properties are not supported in Visual Basic.NET, default properties with parameters are supported. To
understand the difference between the two types, consider that parametered default properties always have an index. An example is
the default property of ADO recordset: the Fields collection. The code:
Dim rs As ADODB.Recordset
rs("CompanyName") = "SomeCompany"
rs!CompanyName = "SomeCompany"
is actually a shortcut for:
Dim rs As ADODB.Recordset
rs.Fields("CompanyName").Value = "SomeCompany"
rs.Fields!CompanyName.Value = "SomeCompany"
In this case, the Fields property is parametered, and so the usage is valid in Visual Basic.NET; however, the default property of the
Fields property, Value, is parameterless, so the correct usage in Visual Basic.NET is:
Dim rs As ADODB.Recordset
rs("CompanyName").Value = "SomeCompany"
rs!CompanyName.Value = "SomeCompany"
This example and most other default properties are resolved for you when the project is upgraded, so resolving them in Visual Basic
6.0 is simply a good programming practice. However, you should avoid using default properties with the Object and Variant
datatypes, as these cannot be resolved and you will have to fix the code yourself in the upgraded project.

Avoid Null Propagation

Previous versions of Visual Basic supported Null propagation. Null propagation supports the premise that when null is used in an
expression, the result of the expression will itself be Null. In each case in the following example, the result of V is always Null.
Dim V
V = 1 + Null
V = Null + Right$("SomeText", 1)
V = Right("SomeText", 0)
Null propagation is not supported in Visual Basic.NET. The statement 1+Null will generate a type mismatch in Visual Basic.NET.
Additionally, where Visual Basic 6.0 had two versions of the Left function—Left$ returning a string, Left returning a variant which
could be Null—Visual Basic.NET only has one version, Left, which always returns a string.

In order to be compatible with both Visual Basic 6.0 and Visual Basic.NET you should always write code to test for Null instead of
relying on Null propagation. Furthermore, in Visual Basic.NET, the following functions will no longer return Null:
Chr Mid
Command Oct
CurDir Right
Date RTrim
Environ Space
Error Str
Hex Time
LCase Trim

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


LTrim UCase
Null propagation is commonly used in database applications, where you need to check if a database field contains Null. In these cases
you should check results using the function IsNull() and perform the appropriate action.

A related issue involves concatenating a string with a Null value. When programming with database objects, it is common practice to
concatenate an "empty string" to a field to ensure that Null values are coerced to an empty string. For example:
MyString = rs!Field1 & ""
This technique is still supported in Visual Basic.NET. When a Null value is concatenated with an empty string (using the & operator),
the result is an empty string.

Use Zero Bound Arrays

Visual Basic 6.0 allowed you to define arrays with lower and upper bounds of any whole number. You could also use ReDim to
reassign a variant as an array. To enable interoperability with other languages, arrays in Visual Basic.NET must have a lower bound of
zero, and ReDim cannot be used unless the variable was previously declared with Dim As Array. Although this restricts the way
arrays can be defined, it does allow you to pass arrays between Visual Basic.NET and any other .NET language. The following
example shows the restriction:
Dim a(1 To 10) As Integer 'LBound must be 0 in VB.NET
Dim v
ReDim v(10) 'Can't use ReDim without Dim in VB.NET
Dim b(10) As Integer 'GOOD: Creates an array of 11 integers
ReDim b(5) As Integer 'GOOD: Can ReDim previously Dimed var
A side effect is that Option Base 0|1 is removed from the language.

When your project is upgraded to Visual Basic.NET, any option base statements are removed from your code. If the array is zero
bound, it is left unchanged. However, if an array is non-zero bound, then the lower bound is removed and a warning is inserted into
the code, as in the following example:
Dim a(1 To 10) As Integer
changes to:
'UPGRADE_WARNING: Lower Bound of array a was changed from 1 to 0
Dim a(10) As Integer
In many cases, the upgraded code will work as it did before. However, if your application logic relies on the lower bound being 1, then
you will need to make some modifications. Dim, ReDim, and LBound statements are marked with warnings to help you review the
changes.

For this reason, you should use zero bound arrays in your Visual Basic 6.0 code, avoid using ReDim as an array declaration, and
avoid using Option Base 1.

Use Constants Instead of Underlying Values

When writing code, try to use constants rather than relying on their underlying values. For example, if you are maximizing a form at
run time, use:
Me.WindowState = vbMaximized 'Good: Constant name used
rather than:
Me.WindowStyle = 2 'Avoid using underlying value
Me.WindowStyle = X 'Avoid using variables
Likewise, use True and False instead of -1 and 0.

In Visual Basic.NET, the values and in some cases the names of some properties and constants have changed. When your project is
upgraded to Visual Basic.NET, most constants are changed automatically for you; however, if you use underlying values or variables
instead of the constant names, many cases cannot be upgraded automatically. Using constant names minimizes the number of
modifications you have to do.

Arrays and Fixed-Length Strings in User-Defined Types

Due to changes made which allow Visual Basic.NET arrays and structures to be fully compatible with other Visual Studio.NET
languages, fixed-length strings are no longer supported in the language. In most cases this is not a problem, because there is a
compatibility class which provides fixed-length string behavior, so the code:

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Dim MyFixedLengthString As String * 100
upgrades to the following:

Dim MyFixedLengthString As New VB6.FixedLengthString(100)


However, fixed-length strings do cause a problem when used in structures (also known as user-defined types). The problem arises
because the fixed-length string class is not automatically created when the user-defined type is created. An additional problem is that
fixed-size arrays are not created, either, when the user-defined type is created.

When your code is upgraded, user-defined types with fixed-length strings or arrays will be marked with a comment telling you to
initialize the fixed-length string or array before using the user-defined type. However, you can shield yourself from this modification
by changing your Visual Basic 6.0 user-defined types to use strings instead of fixed-length strings, and uninitialized arrays instead of
fixed-size arrays. For example:
Private Type MyType
MyArray(5) As Integer
MyFixedString As String * 100
End Type
Sub Bar()
Dim MyVariable As MyType
End Sub
can be changed to:

Private Type MyType


MyArray() As Integer
MyFixedString As String
End Type
Sub Bar()
Dim MyVariable As MyType
ReDim MyVariable.MyArray(5) As Integer
MyVariable.MyFixedString = String$(100, " ")
End Sub
Avoid Legacy Features

Because they have been removed from the language, you should avoid using the following keywords:

• Def<type>

• Computed GoTo/GoSub

• GoSub/Return

• Option Base 0|1

• VarPtr, ObjPtr, StrPtr

• LSet

These are explained in more detail below.

Def<type>
In previous versions of Visual Basic, DefBool, DefByte, DefInt, DefLng, DefCur, DefSng, DefDbl, DefDec, DefDate, DefStr, DefObj
and DefVar were used in the declarations section of a module to define a range of variables as a certain type. For example:
DefInt A-C
defined all variables beginning with the letter A, B, or C as an integer. Instead of using Def<type> statements, you should explicitly
declare variables.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Computed GoTo/GoSub
Computed GoTo/GoSub statements take this form:
On x GoTo 100, 200, 300
These are not supported in Visual Basic.NET. Instead, you should use If statements, and Select Case constructs.

GoSub/Return
GoSub and Return statements are not supported in Visual Basic.NET. In most cases you can replace these with functions and
procedures.

Option Base 0|1


Option Base 0|1 was used to specify the default lower bound of an array. As mentioned previously, this statement has been removed
from the language since Visual Basic.NET natively only supports arrays with a zero lower bound. Non-zero lower bound arrays are
supported through a wrapper class.

VarPtr, ObjPtr, StrPtr


VarPtr, VarPrtArray, VarPtrStringArray, ObjPtr and StrPtr were undocumented functions used to get the underlying memory
address of variables. These functions are not supported in Visual Basic.NET.

LSet
In Visual Basic 6.0, the LSet statement could be used to assign a variable of one user-defined type to another variable of a different
user-defined type. This functionality is not supported in Visual Basic.NET.

Windows APIs

Many APIs can be used exactly as they were in Visual Basic 6.0, with the caveat that you have to adjust your data types accordingly.
The Visual Basic 6.0 Long datatype is now the Visual Basic.NET Integer datatype, and the Visual Basic 6.0 Integer datatype is now
the Visual Basic.NET Short datatype. During the upgrade, these changes are made for you, and simple APIs work exactly the same as
they did in Visual Basic 6.0. For example:
Private Declare Function GetVersion Lib "kernel32" () As Long
Function GetVer()
Dim Ver As Long
Ver = GetVersion()
MsgBox ("System Version is " & Ver)
End Function
changes to:
Private Declare Function GetVersion Lib "kernel32" () As Integer
Function GetVer()
Dim Ver As Integer
Ver = GetVersion()
MsgBox("System Version is " & Ver)
End Function
In addition to numeric datatype upgrades, Visual Basic 6.0 had a fixed-length string data type which is not supported in Visual
Basic.NET, and which is upgraded to a fixed-length string wrapper class. In many cases in Visual Basic 6.0 you can perform the same
action using a normal string. For example:
Private Declare Function GetUserName Lib "advapi32.dll" Alias _
"GetUserNameA" (ByVal lpBuffer As String, ByRef nSize As Long) As Long
Function GetUser()
Dim Ret As Long
Dim UserName As String
Dim Buffer As String * 25
Ret = GetUserName(Buffer, 25)
UserName = Left$(Buffer, InStr(Buffer, Chr(0)) - 1)
MsgBox (UserName)
End Function
can be better written using a normal string explicitly set to length 25 instead of a fixed-length string:
Dim Buffer As String

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Buffer = String$(25, " ")
This is upgraded to Visual Basic.NET as follows:

Declare Function GetUserName Lib "advapi32.dll" Alias _


"GetUserNameA" (ByVal lpBuffer As String, ByRef nSize As Integer) As Integer
Function GetUser()
Dim Ret As Integer
Dim UserName As String
Dim Buffer As String
Buffer = New String(CChar(" "), 25)
Ret = GetUserName(Buffer, 25)
UserName = Left(Buffer, InStr(Buffer, Chr(0)) - 1)
MsgBox(UserName)
End Function
In some cases, Visual Basic.NET better handles passing strings to APIs, since you can optionally declare how you want strings to be
passed using the ANSI and UNICODE keywords.

There are three cases where you may need to make some changes. The first is passing user-defined types that contain fixed-length
strings or byte arrays to APIs. In Visual Basic.NET you may need to change your code, adding the MarshallAs attribute (from
System.Runtime.InteropServices) to each fixed-length string or byte array in the user-defined type. The second case is using the As
Any variable type in a Declare statement. This is not supported in Visual Basic.NET. Variables of type As Any were often used to
pass a variable that was either a string or Null; you can replace this Visual Basic 6.0 usage by declaring two forms of the API, one
with longs, one with strings. For example, the GetPrivateProfileString API has a parameter lpKeyName of type As Any:
Private Declare Function GetPrivateProfileString Lib "kernel32" Alias
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal
lpKeyName As Any, ByVal lpDefault As String, ByVal
lpReturnedString As String, ByVal nSize As Long, ByVal
lpFileName As String) As Long
You can remove the “As Any” by replacing the Declare with two versions; one that accepts a long, and one that accepts a string:

Private Declare Function GetPrivateProfileStringKey Lib "kernel32" Alias


"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal
lpKeyName As String, ByVal lpDefault As String, ByVal
lpReturnedString As String, ByVal nSize As Long, ByVal
lpFileName As String) As Long
Private Declare Function GetPrivateProfileStringNullKey Lib "kernel32"
Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String,
ByVal lpKeyName As Long, ByVal lpDefault As String, ByVal
lpReturnedString As String, ByVal nSize As Long, ByVal
lpFileName As String) As Long
When you wish to pass the value Null to the API, you use the GetPrivateProfileStringNullKey version. Doing it this way means that
the function upgrades to Visual Basic.NET.

The final area where you may need to make some changes is if you are using APIs that perform thread creation, Windows subclassing,
message queue hooking, and so on. Some of these functions will cause a run-time error in Visual Basic.NET. Many of these APIs
have equivalents in Visual Basic.NET or the .NET Framework. You will have to fix these on a case-by-case basis.

Considerations for Forms and Controls

Visual Basic.NET has a new forms package, Windows Forms. Windows Forms is largely compatible with the forms package found in
Visual Basic 6; however, there are some key differences that are outlined below:

• Windows Forms does not support the OLE container control; you should avoid using this control in your Visual Basic 6.0

applications.

• There is no shape control in Windows Forms. Square and rectangular shapes will be upgraded to labels, while ovals and

circles cannot be upgraded. You should avoid using these in your applications.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


• There is no line control in Windows Forms. Horizontal and vertical lines are upgraded to labels. Diagonal lines are not

upgraded, and you should avoid using them.

• Windows Forms has a new set of graphics commands that replace the Form methods Circle, CLS, PSet, Line, and Point.

Because the new object model is quite different from Visual Basic 6.0, these methods cannot be upgraded.

• For the Timer control, setting the Interval property to 0 does not disable the timer; instead the interval is reset to 1. In your

Visual Basic 6.0 projects, you should set Enabled to False instead of setting the Interval to 0.

• Windows Forms has two menu controls, MainMenu and ContextMenu, whereas Visual Basic 6.0 has one menu control,

Menu, which can be opened as a MainMenu or a ContextMenu. Menu controls are upgraded to MainMenu controls, but you will

not be able to use them as ContextMenus; you will have to recreate your ContextMenus.

• Windows Forms has no support for Dynamic Data Exchange (DDE).

• Windows Forms does not support the Form.PrintForm method.

• Although Windows Forms has support for drag-and-drop functionality, the object model is quite different from Visual

Basic 6.0. Therefore, the Visual Basic 6.0 drag-and-drop properties and methods cannot be upgraded.

• The .NET framework has an improved Clipboard object (System.Windows.Clipboard) that offers more functionality and

supports more clipboard formats than the Visual Basic 6.0 Clipboard object. However, because of differences between object

models, clipboard statements cannot be automatically upgraded.

• To ensure your forms are upgraded to the right size, you should always use the default ScaleMode of twips in your

applications. During the upgrade, Visual Basic.NET transforms your forms coordinates from twips to pixels.

• Windows Forms only supports true-type and open-type fonts. If your application uses other fonts, these fonts will be

changed to the system’s default font, and all formatting (size, bold, italic, underline) will be lost. This applies to the default VB6

font MS Sans Serif. For this reason, we recommend you use Arial instead of MS Sans Serif, wherever you have formatted text.

10 Ways to Prepare for VB.NET


Make these 10 changes today to ready yourself—and your code—for Visual Basic.NET.
by Billy Hollis

Get ready for the biggest transition you'll make since you learned Visual Basic. Microsoft's new .NET
framework will change the way you develop software from top to bottom. Microsoft is bringing all its
languages onto a common platform; they'll share the same runtime and use the same datatypes. VB is
changing the most, with many of the changes bringing VB in line with the other languages.
What you need:
Visual Basic 4.0 or later

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


One thing you can be sure of: Many (perhaps most) of your current programs won't run in VB.NET, even
with Microsoft's supplied conversion tool, without some manual intervention. But you can do a few things
to make the migration easier. You can use several coding practices today that will make your VB code
more in line with the next version. You'll still have work when the time comes to migrate, but hopefully
the process will be a lot easier.

Here are 10 tangible things you can do today to make the migration easier. You might already be doing
some of them, because several have long been considered good coding practices. Others are new and
probably unexpected.
1
Stop Using Default Properties and Methods

VB6 and earlier versions allow you to write code like this, where lblTitle is a Label control:
lblTitle = "Top Ten Things"
This works because the label control has a default property, which is Caption. So the preceding line really
means this:
lblTitle.Caption = "Top Ten Things"
VB.NET does away with the concept of default properties and methods in most circumstances. So the first
form won't work in VB.NET. You must use the second form.

Many development shops have long frowned on using default methods and properties, because they make
code more difficult to read. The change in VB.NET gives another, even more compelling reason to do
away with default methods and properties. Even many professional shops use a related construct for data
access coding. It looks like this, where rsTitles is a recordset:
rsTitles("DatePublished").Value = sDate
This line actually means:
rsTitles.Fields _
("DatePublished").Value = _
sDate
In this case, the Fields collection is the default for the Recordset object. Based on the latest information, it
looks like the shorthand form (without the "Fields") will probably work in VB.NET.

10 Ways to Prepare
for VB.NET
2
Control Your Array Bounds

Today, when you declare an array in VB6, you actually get an extra element. That is, if you have this
line, then VB sets aside space for six array elements, starting with index zero and going to index five:
Dim sSubjects(5) As String
Old-time VBers commonly use only elements one through five (I'm guilty of this one). We're going to
have to adapt, I'm afraid. When you use this same line in VB.NET, you get an array of exactly five

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


elements, with the index starting at zero and ending at four.

Losing the top-most array element is my nominee for biggest breaker of old code. Converting old code
and getting all the index handling right will be a huge headache. Your action item is to stop using the
top array element on arrays. It might be tough to fix old code, but at least you can stop the damage on
code written from this point.

10 Ways to Prepare for


VB.NET
3
Stop Making Direct References to Controls

Since version 1, VB has considered controls on a form to be Public. You commonly see code in a
BAS module do something like this:
sTitle = frmArticleEntry.txtTitle.Text
This fails in VB.NET (see Figure 1). You can make it work by explicitly declaring the control
txtTitle on frmArticleEntry as Public Shared. But that's not the best solution.

Figure 1 Change Your Code So It Works in VB.NET Click here.

Since VB4, many professional developers have recommended that all communication of data with a
form take place through custom property procedures. Any code outside the form reads data from or
writes data to the form through these procedures.

For example, suppose you have a form named frmOptions that uses five option buttons, named
optFormat(0) through optFormat(4), to allow the user to specify a report's format type. You need to
find the format type from outside the form (say from a BAS module). With old-fashioned VB syntax,
you would access the format type like this:
For nIndex = 0 To 4
If frmOptions.optFormat(nIndex) Then
nFormatNumber = nIndex
Exit For
End If
Next nIndex
Later, however, you might have to change either the control name or the number of option buttons. Or
you might have to switch to a combo box holding the format types because they increase in number
and start varying. In that case, code from outside the form, such as the preceding lines, would all have

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


to change.

Instead, add a property to the form at the outset to allow outside code to fetch the format type. You
could call the property FormatType. You place this code in the frmOptions code module:
Public Property Get FormatType() As _
Long
For nIndex = 0 To 4
If frmOptions.optFormat(nIndex) _
Then
FormatType = nIndex
Exit For
End If
Next nIndex
End Property
Now calling code from outside the form can get the format type with a single line:
nFormatNumber = frmOptions.FormatType
If you have to change the controls for the format type, adjust the property procedure inside frmOptions
to reflect the changes. For example, if you switch to a combo box, the property procedure looks like
this:
Public Property Get FormatType() As _
Long
FormatType = cboFormat.ListIndex
End Property
Calling code from outside frmOptions doesn't need to change at all. Ideally, the property procedures
would contain some error checking, which I have left out for simplicity. You also want Property Let
procedures for setting the controls from outside the form.

Doing this extra work now has some immediate benefits, such as easier switching of control types, and
will make the transition to .NET easier to boot.

10 Ways to Prepare
for VB.NET
4
Make All Parameters ByRef or ByVal Explicitly

Today, if you fail to make a parameter ByRef or ByVal explicitly, whether it becomes ByRef or
ByVal depends on what type of parameter it is. If it's an intrinsic type (integer, long, Boolean, string,
and so on), then it's ByRef by default. Otherwise, it's ByVal. This allows you to pass in parameters to
subroutines or functions (without making them ByRef) and have the underlying routine change them
and pass them back. This practice is usually considered sloppy, and now there's an even better reason
not to do it.
In VB.NET, all parameters are ByVal by default. You must declare a subroutine or function explicitly
as ByRef to get it to change a parameter. This change can lead to subtle, hard-to-find bugs if you
continue using the older convention. My recommendation: Make it a coding standard to make all
parameters explicitly ByVal or ByRef. This works now and later.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html

Das könnte Ihnen auch gefallen