2

Please have a look at the following code, which I have run in VB6 and .NET:

Private Sub Form_Load()
Dim TestArray3() As String
TestArray3 = TestArrayFunction

End Sub

Private Function TestArrayFunction() As String()
    Dim TestArray1(0 To 1) As String
    Dim TestArray2() As String
    TestArray1(0) = "Monday"
    TestArray1(1) = "Tuesday"
    TestArray2 = TestArray1
    TestArray1(0) = "Wednesday"
End Function

When the program gets to the end of TestArrayFunction in VB6, the value of TestArray2(0) is "Monday", however when run in .NET, it is "Wednesday". I understand in .NET that an Array is an object and has two references pointing to it in TestArrayFunction. Why is this not the case in VB6?

w0051977
  • 15,099
  • 32
  • 152
  • 329
  • So you are trying a "reverse migration" of your skills from VB.Net to VB6, maybe just for one project? You could learn about the differences between VB6 and VB.Net by reading [some](http://msdn.microsoft.com/en-us/library/skw8dhdd.aspx) [of](http://www.4guysfromrolla.com/webtech/053001-1.shtml) the material to help VB6 users learn VB.Net. Might help you deduce how VB6 works. Alternatively there's [other](http://stackoverflow.com/questions/1595737/good-tutorial-for-visual-basic-6) [questions](http://stackoverflow.com/questions/166138/learning-vb6) on learning VB6 for experienced programmers – MarkJ Feb 12 '12 at 19:10
  • The VB6 golden age was too early from the .net or the Java times. Visual Basic is a third-generation event-driven programming language and integrated development environment (IDE) from Microsoft for its Component Object Model (COM) programming model first released in 1991, final release was version 6 in 1998 (VB6) and declared legacy during 2008. Visual Basic.net is part of the .net framework (like C# or F#), first released in 2002. – Pedro Polonia Apr 10 '17 at 15:43

3 Answers3

7

This is to add to Dabblernl's response.

Long story made short, VB6 never really had a general reference type. Being built on COM, the only reference type it has (Dim ... As Object) is one for COM-based (or COM styled) classes. The Variant type was only good at boxing other types.

As to why ByRef works with arrays ...

The evolution of many dialects of BASIC, including VB6, adopted/adapted the paradigm of FORTRAN when it came to subroutines and functions; namely, parameters are passed by address (hence, ByRef is the default), and functions return their results by value. Add to this that BASIC never really had the concept of an address or a reference: VB6 (and earlier versions) would simulate addresses with 32-bit (signed) integers and otherwise would cope (in strange ways) via peculiar rules of the DECLARE SUB/FUNCTION statement and the (shoe-horned) AddressOf operator and VarPtr/StrPtr functions.

Final note: Since VB6 classes are COM-style, VB6 has the SET statement. The reason for this is that without the SET, an l-value = r-value situation is an implied LET statement. COM supports the notion of a default property (with and without parameters); LET objA = objB is interpreted as LET objA.DefaultPropOfA = objB.DefaultPropOfB. SET, on the other hand, makes objA take on the reference to the same object that objB references.

The Visual Basic of .NET is a nice and powerful language, with far fewer shortcomings and warts than VB6. However, it does have big differences from its legacy cousin. These differences have made long time VB6 users grouchy, and I suspect it has made many VB.NET users confused when they're asked to deal with VB6 code.

BTW, a VB6 coder would deal with the array within a class issue in this way:

Public Property Get DaysOfWeek(ByVal index As Integer) As String
  DaysOfWeek = m_strDaysOfWeek(index)
End Property

Public Property Let DaysOfWeek(ByVal index As Integer, ByRef value As String)
  m_strDaysOfWeek(index) = value
End Property

That would allow syntax of strDay = clsDateTime.DaysOfWeek(1) and clsDateTime.DaysOfWeek(2)="Tuesday" to work as desired.

rskar
  • 4,607
  • 25
  • 21
2

I am struggling with this nearly daily. While it is perfectly possible to pass an array ByRef to a Function call, the '=' sign will make a shallow copy.

But there is more strange behaviour of arrays in VB6, Suppose you have the following DateTimeClass classmodule in VB6:

Option Explicit

Private m_strDaysOfWeek() As String

Public Property Get DaysOfWeek() As String()

    DaysOfWeek = m_strDaysOfWeek()

End Property

Public Property Let DaysOfWeek(strDaysOfWeek() As String)

    m_strDaysOfWeek() = strDaysOfWeek

End Property

Private Sub Class_Initialize()
    ReDim m_strDaysOfWeek(7)
    m_strDaysOfWeek(1) = "Monday"
End Sub

You would expect to be able to write code like:

Dim clsDateTime As New DateTimeClass
Dim strDay As String

strDay = clsDateTime.DaysOfWeek(1)

Or:

clsDateTime.DaysOfWeek(2)="Tuesday"

But you can't. You have to do it like this:

Dim clsDateTime As New DateTimeClass
Dim strDay As String
Dim strDays() As String

strDays = clsDateTime.DaysOfWeek
strDay = strDays(1)
strDays(2) = "Tuesday"
clsDateTime.DaysOfWeek = strDays

What the reasons of the VB6 team were at the time to implement it thus? I don't know... I have abandoned the VB6 arrays and use Collections and Dictionaries nearly exclusively.

Dabblernl
  • 15,831
  • 18
  • 96
  • 148
  • @Dabbernl, Thanks. This does make sense. One question I have is about using the ERASE keyword. In Vb.net you can set an array to NOthing, however you cannot do this in vb6. Are vb6 arrays objects? Thanks – w0051977 Feb 11 '12 at 22:41
  • @w0051977 it seems they are not. I'd like to find some documentation about this though. – Dabblernl Feb 12 '12 at 08:03
1

VB6 copies the array, and the last statement of your Function only changes the original copy.

Since you know .Net broke compatibility with VB I'm not sure where the confusion comes from.

Bob77
  • 13,167
  • 1
  • 29
  • 37