VB6 и .NET - различия в массивах - PullRequest
2 голосов
/ 11 февраля 2012

Пожалуйста, посмотрите на следующий код, который я запустил в VB6 и .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

Когда программа доходит до конца TestArrayFunction в VB6, значение TestArray2 (0)это «понедельник», однако при запуске в .NET это «среда».Я понимаю в .NET, что массив является объектом и имеет две ссылки, указывающие на него в TestArrayFunction.Почему это не так в VB6?

Ответы [ 3 ]

7 голосов
/ 12 февраля 2012

Это должно добавить к ответу Дабблернла.

Короче говоря, VB6 никогда не имел общего ссылочного типа.Будучи построенным на COM, единственный ссылочный тип (Dim ... As Object) - это тип для классов на основе COM (или в стиле COM).Тип Variant был хорош только для бокса других типов.

Что касается того, почему ByRef работает с массивами ...

Эволюция многих диалектов BASIC, включая VB6, приняла / адаптировала парадигмуФортран, когда дело доходит до подпрограмм и функций;а именно, параметры передаются по адресу (следовательно, ByRef является значением по умолчанию), а функции возвращают свои результаты по значению.Добавьте к этому, что BASIC никогда не имел понятия адреса или ссылки: VB6 (и более ранние версии) имитировал адреса с 32-разрядными (подписанными) целыми числами и в противном случае (странным образом) справлялся бы с помощью особых правил DECLARE SUB./ FUNCTION оператор и (операторский башмак) оператор AddressOf и функции VarPtr / StrPtr.

Заключительное примечание: Поскольку классы VB6 выполнены в стиле COM, в VB6 есть оператор SET.Причина этого заключается в том, что без SET ситуация l-значение = r-значение является подразумеваемым оператором LET.COM поддерживает понятие свойства по умолчанию (с параметрами и без параметров);LET objA = objB интерпретируется как LET objA.DefaultPropOfA = objB.DefaultPropOfB.SET, с другой стороны, заставляет objA ссылаться на тот же объект, на который ссылается objB.

Visual Basic .NET - хороший и мощный язык, с гораздо меньшими недостатками и недостатками, чем VB6.Тем не менее, он имеет большие отличия от своего двоюродного брата.Эти различия заставляли пользователей VB6 долгое время ворчать, и я подозреваю, что многие пользователи VB.NET были сбиты с толку, когда их просили разобраться с кодом VB6.

Кстати, кодировщик VB6 будет работать с массивом внутрипроблема класса следующим образом:

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

Это позволило бы синтаксису strDay = clsDateTime.DaysOfWeek(1) и clsDateTime.DaysOfWeek(2)="Tuesday" работать так, как нужно.

2 голосов
/ 12 февраля 2012

Я борюсь с этим почти ежедневно. Хотя вполне возможно передать массив ByRef в вызов функции, знак '=' сделает мелкую копию.

Но в VB6 есть более странное поведение массивов. Предположим, у вас есть следующий модуль класса DateTimeClass в 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

Вы ожидаете, что сможете написать код вроде:

Dim clsDateTime As New DateTimeClass
Dim strDay As String

strDay = clsDateTime.DaysOfWeek(1)

Или:

clsDateTime.DaysOfWeek(2)="Tuesday"

Но ты не можешь. Вы должны сделать это так:

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

Какие причины были у команды VB6 в то время, чтобы реализовать это таким образом? Я не знаю... Я отказался от массивов VB6 и почти исключительно использую коллекции и словари.

1 голос
/ 12 февраля 2012

VB6 копирует массив, а последний оператор вашей функции изменяет только оригинальную копию.

Поскольку вы знаете, что .Net нарушила совместимость с VB, я не уверен, откуда возникла путаница.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...