Is it possible to declare a local/class instance member reference variable in VB.net to read/update same object referred by another variable

StackOverflow https://stackoverflow.com/questions/11415250

Question

In C++, it is possible to do:

int x;
int& foo = x;

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

But is an equivalent possible in Visual Basic .net (VB.net)?

I am aware of the ByRef term in VB.net but I have only seen (and by extensive research) this in passing parameters by reference to functions/subroutines, so that the function modifies the same variable declared by the calling code.

But I haven't seen ByRef used to declare variables (as class members or local variables). I have tried to use ByRef to do such a declaration but I get compiler errors for each ordering of the declaration I try.

The reason why I want to do this is because I want a class instance to be able to refer to a variable declared in another class instance.

Specifically, I am working on some existing VB.net code where program logic is mixed up with UI logic in VB.net form classes. I want to separate the program logic out of the form code so that it can be more easily reused. To do this I need the program logic code to be able to 'talk' to the form code so I need access to its variables.

I am using Visual Studio 2010 Express with VB.net and would prefer to remain within this environment even though I am aware that full Visual Studio has extended capabilities.

Was it helpful?

Solution

Pointers exist but they're called object references

(Now other posters, please don't quibble with me about the actual differences here. I am talking about the high level task the OP wants to accomplish)

Obviously you can't do literally what you've said - that is, surgically manipulate one member. But if you have control of the code, you can do almost as well. And from what you describe is your problem, this method will be much better, as you can pass references to an object that has many members you wish to update, instead of having to pass many individual pointers.

First define a class:

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

Now the equivalent of the code you posted:

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; 

If what you're doing is trying to pass pointers to, say, every control on your form's value to a sub, like so:

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

You can use the method provided by superbDeveloper, and use the ByRef keyword on the definition of the DoSubmit Sub:

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

However this just gives you a 2-layer separation. Look into MVP, MVC, etc - however consider submitting the entire view worth of data. It's a lot of research you you may settle with what you have now. For example your business logic will be firing events on the form as it changes the form values (well, actually, they won't fire until the sub exits, due to the way VB deals with byref properties [=temp variable], but it needs to be considered).

You can also map an object's properties to a Form's properties with other libraries. Check out VALUE INJECTOR on the web. It can take a webform/winform and maybe even a WPF form and map the control values to and from an object you have predefined. Excellent for complete separation.

OTHER TIPS

Hi well not sure about VB.NET but I know how do it in C#, therefore I did the solution in C# and then i used a C# to VB.NET convertor to get the VB.NET code. maybe it might help you:

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

C# Code

protected void TestFoo()
{

    string strFooA = string.Empty;

    GetFoo(ref strFooA);

    Response.Write(strFooA);
}

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

VB.NET converted

    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

Pointers don't exist in the .NET framework like they do in C/C++, so you won't be able to directly achieve what you want.

There are some possible solutions on this SO page

See @NathanW answer on there:

If you are using VB the only thing that is really close to a pointer is a IntPtr. If you have access to C# you can use unsafe C# code to do pointer work.

In Addition

If you want to be able to use references then you can achieve this by using a class:

Private Class RefClass
    Public x As Integer
End Class

Then you can reference one from the other:

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

You may already know enough to get the job done from the info at http://www.dreamincode.net/forums/topic/135354-reference-types-value-types-byval-byref/ ; however, your remark "ByRef is not required in declaration of local variables (and possibly class variables)" left me wondering if there's some confusion here.

For starters, the C++ example above, int x; int& foo = x; confuses what is meant by a "reference". My C++ isn't very strong, but, semantically speaking, I believe this C++ reference operates more like an aliasing mechanism. In VB (and C#) a reference operates like an identification code that locates an instance of a class in memory. Neither VB or C# has anything like the C++ reference type.

By now, you probably already know you can pass in your Form as a ByVal parameter, and change its properties and fields without problem. (ByVal is the default in VB.NET, so you don't even need to use it - in VB6 ByRef was the default.) If you're happy enough, you can skip the rest. But, yeah, in the case of .NET Reference variables, assuming:

Dim objA as New MyClass()
Dim objB as MyClass = objA

Then objA and objB both reference the very same instance of MyClass. You can modify via objA and objB, and you can read back from either objA or objB, because they each affect the very same instance. You can pass either objA or objB into some subroutine Foo with parameter objC As Object passed ByVal (i.e. Sub Foo(ByVal objC As Object) ) and Foo can then modify that same instance too.


The ByRef of VB and the ref of C# indicate a modifiable parameter, which means some "identification code" reference is passed instead of a value. Yet this ByVal vs. ByRef thing is clear as mud because in .NET there is a distinction made between "Value" types and "Reference" types that confuses many on whether a ByRef or ref is needed or not.

Visual Basic and C# dichotomizes variables (and data types) into two species: the "Value" (or "Structure"), and the "Reference" (or "Class").

The "Value" type means an actual collection of bits that represents an Integer, or a Boolean, or even a bitmap, or some other kind of object. In old school parlance, this is the "image" of the instantiation of an object. It is the state space of the object. It is what makes an object essentially itself, independent of where in memory it may be.

The "Reference" type means a code (which might look like an integer or a pointer) that somehow indicates the data type of the object and where in memory it resides. The computer will interpret a "Reference" to obtain the actual image of the object (i.e. its "Value").

When a "Value" parameter is passed ByVal, that means a new object is created that is in the identical image of the original expression being passed, and it is upon this copy that the function or method operates. The original image of the "Value" cannot be affected.

When a "Value" parameter is passed ByRef, that means a new "Reference" variable is created, and that "Reference" variable will contain the information that will interpret back to the image of the original "Value". Now the original image of the "Value" can be changed.

When a "Reference" parameter is passed ByVal, its "identification code", which gets interpreted back to the actual image of the object, gets copied. It is upon this copy of the code that the function or subroutine or method operates. This copy still points to the actual image of the object. Which means that an object of a Reference variable that is passed by ByVal can still have its image (i.e. its "Value") changed. However, the code of the original "Reference" itself cannot be changed.

(Note that the String type is an odd duck: It will behave as if it were a "Value" parameter even though it is in fact a "Reference" type. Hence a String passed ByVal will not be affected in the same way any other class would. Actually, String is an example of an immutable type - which means that steps are taken to prevent changes to its "Value".)

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top