w0051977
w0051977

Reputation: 15807

VB6 and .NET - array differences

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?

Upvotes: 2

Views: 1882

Answers (3)

rskar
rskar

Reputation: 4657

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.

Upvotes: 7

Dabblernl
Dabblernl

Reputation: 16101

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.

Upvotes: 2

Bob77
Bob77

Reputation: 13267

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.

Upvotes: 1

Related Questions