VB6 和 .NET - 数组差异
请看一下我在 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 中运行时,今天是“星期三”。我在 .NET 中理解数组是一个对象,并且在 TestArrayFunction 中有两个指向它的引用。为什么VB6中不是这样呢?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是对 Dabblernl 的回应的补充。
长话短说,VB6 从未真正拥有通用引用类型。由于构建在 COM 之上,它拥有的唯一引用类型 (Dim ... As Object) 是基于 COM 的(或 COM 样式)类的引用类型。变异型只擅长拳击其他类型。
至于为什么 ByRef 与数组一起工作......
许多 BASIC 方言的演变,包括 VB6,在子例程和函数方面采用/适应了 FORTRAN 的范例;即,参数通过地址传递(因此 ByRef 是默认值),函数通过值返回结果。除此之外,BASIC 从未真正具有地址或引用的概念:VB6(和早期版本)将使用 32 位(有符号)整数模拟地址,否则将通过 DECLARE SUB 的特殊规则进行处理(以奇怪的方式) /FUNCTION 语句以及(鞋履式)AddressOf 运算符和 VarPtr/StrPtr 函数。
最后注意:由于 VB6 类是 COM 风格的,因此 VB6 具有 SET 语句。原因是如果没有 SET,左值 = 右值的情况就是隐含的 LET 语句。 COM 支持默认属性的概念(带参数和不带参数);
LET objA = objB
被解释为LET objA.DefaultPropOfA = objB.DefaultPropOfB
。另一方面,SET 使 objA 接受对 objB 引用的同一对象的引用。.NET 的 Visual Basic 是一种优秀而强大的语言,其缺点和缺陷比 VB6 少得多。然而,它与它的传统表兄弟确实有很大的不同。这些差异让 VB6 的长期用户感到不满,而且我怀疑这也让许多 VB.NET 用户在被要求处理 VB6 代码时感到困惑。
顺便说一句,VB6 编码器会以这种方式处理类问题中的数组:
这将允许使用
strDay = clsDateTime.DaysOfWeek(1)
和clsDateTime.DaysOfWeek(2)=" 语法星期二”
按需要工作。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 asLET 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:
That would allow syntax of
strDay = clsDateTime.DaysOfWeek(1)
andclsDateTime.DaysOfWeek(2)="Tuesday"
to work as desired.我几乎每天都在为此苦苦挣扎。虽然完全可以将数组 ByRef 传递给函数调用,但“=”符号将进行浅复制。
但是 VB6 中的数组有更奇怪的行为,假设您在 VB6 中有以下 DateTimeClass 类模块:
您希望能够编写如下代码:
或者:
但您不能。你必须这样做:
VB6团队当时这样做的原因是什么?我不知道...
我已经放弃了 VB6 数组,几乎只使用集合和字典。
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:
You would expect to be able to write code like:
Or:
But you can't. You have to do it like this:
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.
VB6 复制数组,而 Function 的最后一条语句仅更改原始副本。
既然你知道 .Net 破坏了与 VB 的兼容性,我不确定这种混乱从何而来。
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.