2

在 C++ 中,可以这样做:

int x;
int& foo = x;

// foo is now a reference to x so this sets x to 56
foo = 56;

但是在 Visual Basic .net (VB.net) 中是否有可能?

我知道ByRefVB.net 中的术语,但我只看到(并且通过广泛的研究)通过引用函数/子例程传递参数,以便函数修改调用代码声明的相同变量。

但是我还没有看到ByRef用于声明变量(作为类成员或局部变量)。我曾尝试使用ByRef来做这样的声明,但是对于我尝试的声明的每个排序,我都会遇到编译器错误。

我之所以要这样做是因为我希望一个类实例能够引用另一个类实例中声明的变量。

具体来说,我正在处理一些现有的 VB.net 代码,其中程序逻辑与 VB.net 表单类中的 UI 逻辑混合在一起。我想将程序逻辑从表单代码中分离出来,以便更容易重用。为此,我需要程序逻辑代码能够与表单代码“对话”,因此我需要访问其变量。

我正在使用带有 VB.net 的 Visual Studio 2010 Express,并且更愿意留在这个环境中,即使我知道完整的 Visual Studio 具有扩展功能。

4

4 回答 4

2

嗨,我不确定 VB.NET,但我知道如何在 C# 中做到这一点,因此我在 C# 中完成了解决方案,然后我使用 C# 到 VB.NET 转换器来获取 VB.NET 代码。也许它可以帮助你:

http://www.developerfusion.com/tools/convert/csharp-to-vb/

C# 代码

protected void TestFoo()
{

    string strFooA = string.Empty;

    GetFoo(ref strFooA);

    Response.Write(strFooA);
}

private void GetFoo(ref string strFooA)
{
    strFooA = "FooA";
}

VB.NET 转换

    Protected Sub TestFoo()

      Dim strFooA As String = String.Empty

      GetFoo(strFooA)

      Response.Write(strFooA)
    End Sub

    Private Sub GetFoo(ByRef strFooA As String)
      strFooA = "FooA"
    End Sub
于 2012-07-10T14:34:46.823 回答
2

指针存在,但它们被称为对象引用

(现在其他海报,请不要在这里与我争辩实际的差异。我说的是OP想要完成的高级任务)

显然,你不能按照你所说的去做——即通过外科手术操纵一个成员。但是,如果您可以控制代码,则几乎可以做到。从您所描述的问题来看,这种方法会更好,因为您可以将引用传递给具有许多要更新的成员的对象,而不必传递许多单独的指针。

首先定义一个类:

Class MyScreenValues
    ' Properties will work... using public fields for brevity
    Public TextBox1Value as String
    Public SpinControl1Value as Integer
    public CheckBox1Value as Boolean
End Class

现在相当于您发布的代码:

Dim x as new MyScreenValues    'int x; 
dim foo as MyScreenValues = x  'int& foo = x;  
'// c++:  foo is now a reference to x so this sets x to 56 
'// .net: foo is now a reference to x so this sets x.SpinControl1Value to 56 
foo.SpinControl1Value = 56; 

如果您正在尝试将指针传递给表单值上的每个控件,例如:

Button1_Click(...
    Dim MyObject as new BusinessObject
    MyObject.DoSubmit(TextBox1.Text, SpinButton1.Value, CheckBox1.Checked)

您可以使用 superDeveloper 提供的方法,并在 DoSubmit Sub 的定义中使用 ByRef 关键字:

Public Sub DoSubmit(ByRef Name as String, ByRef Age as Integer, ByRef Employed as boolean)
    ... business logic...

然而,这只是给你一个 2 层分离。查看 MVP、MVC 等 - 但是考虑提交整个视图的数据。你可以用你现在拥有的东西来解决很多研究。例如,您的业务逻辑将在更改表单值时触发表单上的事件(实际上,由于 VB 处理 byref 属性 [=temp 变量] 的方式,它们在子退出之前不会触发,但它需要考虑)。

您还可以使用其他库将对象的属性映射到表单的属性。在网络上查看VALUE INJECTOR。它可以采用 webform/winform,甚至可能是 WPF 表单,并将控件值映射到您预定义的对象或从您预定义的对象映射出控件值。非常适合完全分离。

于 2012-07-10T15:11:25.043 回答
1

.NET 框架中不像 C/C++ 中那样存在指针,因此您将无法直接实现您想要的。

此 SO 页面上有一些可能的解决方案

请参阅@NathanW 那里的答案:

如果您使用的是 VB,那么唯一真正接近指针的是 IntPtr。如果您有权访问 C#,则可以使用不安全的 C# 代码来执行指针工作。

此外

如果您希望能够使用引用,那么您可以通过使用一个类来实现:

Private Class RefClass
    Public x As Integer
End Class

然后你可以互相引用:

Dim bar As New RefClass
Dim foo As RefClass = bar

bar.x = 45

Debug.WriteLine(bar.x) 'outputs 45
Debug.WriteLine(foo.x) 'outputs 45
于 2012-07-10T14:47:09.187 回答
1

你可能已经知道足够的信息来完成工作了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 也可以修改同一个实例。


ByRefVB 和C#的ref表示一个可修改的参数,这意味着传递一些“标识码”引用而不是一个值。然而,这个 ByVal 与 ByRef 的事情一清二楚,因为在 .NET 中,“值”类型和“引用”类型之间存在区别,这使许多人对是否需要 aByRefref是否需要感到困惑。

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.

于 2012-07-10T20:48:31.933 回答