请看一下我在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
当程序在VB6中到达TestArrayFunction的末尾时,TestArray2(0)的值为“Monday”,但是在.NET中运行时,它是“Wednesday”。我在.NET中理解,Array是一个对象,并且在TestArrayFunction中有两个引用它的引用。为什么在VB6中不是这种情况?
答案 0 :(得分:7)
这是为了增加Dabblernl的回应。
长篇故事简而言之,VB6从未真正拥有一般参考类型。在COM上构建,它具有的唯一引用类型(Dim ... As Object)是基于COM(或COM样式)类的引用类型。 Variant类型只擅长拳击其他类型。
至于为什么ByRef与数组一起工作......
BASIC的许多方言的演变,包括VB6,在涉及子程序和功能时采用/适应了FORTRAN的范式;即,参数按地址传递(因此,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引用的相同对象的引用。
.NET的Visual Basic是一种优秀而强大的语言,缺点和瑕疵比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"
的语法按预期工作。
答案 1 :(得分:2)
我几乎每天都在努力解决这个问题。尽管将数组ByRef传递给函数调用是完全可能的,但'='符号将会生成浅表副本。
但是在VB6中有更多奇怪的数组行为,假设你在VB6中有以下DateTimeClass类模块:
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阵列,几乎只使用了集合和字典。
答案 2 :(得分:1)
VB6复制数组,函数的最后一个语句只更改原始副本。
既然你知道.Net打破了与VB的兼容性,我不确定混淆来自何处。