你可能已经知道足够的信息来完成工作了http://www.dreamincode.net/forums/topic/135354-reference-types-value-types-byval-byref/;但是,您的评论“在声明局部变量(可能还有类变量)时不需要 ByRef”让我想知道这里是否有一些混淆。
对于初学者来说,上面的 C++ 示例int x; int& foo = x;
混淆了“引用”的含义。我的 C++ 不是很强大,但是,从语义上讲,我相信这个 C++ 引用更像是一种别名机制。在 VB(和 C#)中,引用的操作类似于识别代码,用于在内存中定位类的实例。VB 或 C# 都没有类似 C++ 引用类型的东西。
到目前为止,您可能已经知道可以将 Form 作为 ByVal 参数传递,并且可以毫无问题地更改其属性和字段。(ByVal 是 VB.NET 中的默认设置,因此您甚至不需要使用它 - 在 VB6 中 ByRef 是默认设置。)如果您足够满意,您可以跳过其余部分。但是,是的,对于 .NET 引用变量,假设:
Dim objA as New MyClass()
Dim objB as MyClass = objA
然后 objA 和 objB 都引用了同一个 MyClass 实例。您可以通过 objA 和 objB 进行修改,也可以从 objA 或 objB 回读,因为它们都会影响同一个实例。您可以将 objA 或 objB 传递到带有参数 objC 的某个子例程 Foo 中,因为 Object 传递了 ByVal (即Sub Foo(ByVal objC As Object)
),然后 Foo 也可以修改同一个实例。
ByRef
VB 和C#的ref
表示一个可修改的参数,这意味着传递一些“标识码”引用而不是一个值。然而,这个 ByVal 与 ByRef 的事情一清二楚,因为在 .NET 中,“值”类型和“引用”类型之间存在区别,这使许多人对是否需要 aByRef
或ref
是否需要感到困惑。
Visual Basic 和 C# 将变量(和数据类型)分为两类:“值”(或“结构”)和“引用”(或“类”)。
“值”类型表示表示整数、布尔值、甚至位图或其他类型对象的位的实际集合。用老派的说法,这是对象实例化的“图像”。它是对象的状态空间。它使对象本质上是自身,与它在内存中的位置无关。
“引用”类型意味着一个代码(可能看起来像一个整数或指针),它以某种方式指示对象的数据类型以及它在内存中的位置。计算机将解释“参考”以获得对象的实际图像(即其“值”)。
当传递“值”参数时ByVal
,这意味着创建了一个新对象,该对象与传递的原始表达式具有相同的图像,并且函数或方法在此副本上运行。“价值”的原始形象不会受到影响。
当传递“值”参数时ByRef
,这意味着创建了一个新的“参考”变量,并且该“参考”变量将包含将解释回原始“值”图像的信息。现在可以更改“值”的原始图像。
当一个“参考”参数被传递ByVal
时,它的“识别码”,被解释回对象的实际图像,被复制。函数或子例程或方法正是在此代码副本上运行的。该副本仍然指向对象的实际图像。这意味着传递的引用变量的对象ByVal
仍然可以更改其图像(即其“值”)。但是,原始“参考”本身的代码不能更改。
(请注意,String 类型是一个奇怪的鸭子:它的行为就好像它是一个“Value”参数,即使它实际上是一个“Reference”类型。因此,通过 ByVal 传递的 String 不会以与任何其他方式相同的方式受到影响类会。实际上,String 是不可变类型的一个示例 - 这意味着已采取措施防止更改其“值”。)
When a "Reference" parameter is passed ByRef
, one now has created a new "Reference" object that points to the original "Reference" object (that, in turn, points to the "Value" of some other object via its "identification code"). The use of ByRef
on a "Reference" allows one to modify (or create anew) the "identification code" of the original "Reference" object being passed as a parameter. A function or subroutine or method that performs a swap operation will use ByRef on "Reference" parameters.