2

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.

therobyouknow
  • 6,604
  • 13
  • 56
  • 73
  • What I'm looking for appears to be possible - here is a very good explanation: http://www.dreamincode.net/forums/topic/135354-reference-types-value-types-byval-byref/ Assuming it is correct, ByRef is not needed at all: assigning one variable to another appears to be default behavior and ByRef is not required in declaration of local variables (and possibly class variables). – therobyouknow Jul 10 '12 at 15:06

4 Answers4

2

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
zulucoda
  • 818
  • 12
  • 24
  • Thanks I will try it out and follow up with the outcomes. I'd certainly like to +1 / accept your answer if it does work. – therobyouknow Jul 10 '12 at 14:37
  • 1
    @therobyouknow cool mate. you may also try converting c++ to c# http://sourceforge.net/projects/convetercpptocs/ then convert c# to vb.net, sounds hectic but might work. good luck. – zulucoda Jul 10 '12 at 14:49
  • thanks for the reference @superbDeveloper to the converter. I'll get back asap. I'm grateful (but overwhelmed) by all the responses here! I'm keen to reward yourselves for your time and input asap. – therobyouknow Jul 10 '12 at 15:47
  • 1
    +1 x 2 Thanks @superbDeveloper for the conversion utilities. The other answers from other posters are useful too so together they all help! – therobyouknow Jul 10 '12 at 21:44
2

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.

Community
  • 1
  • 1
FastAl
  • 6,194
  • 2
  • 36
  • 60
1

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
Community
  • 1
  • 1
Matt Wilko
  • 26,994
  • 10
  • 93
  • 143
  • Nor do pointers exist in Java but one can declare several variables each referring to the same object. I don't require the use of pointers just the concept of *references* - which I know are already used for passing objects by reference in function/sub calls *in .net* – therobyouknow Jul 10 '12 at 14:49
  • 1
    @therobyouknow - I have added some additional information to my answer – Matt Wilko Jul 10 '12 at 14:58
  • +1 x 2 @Matt Wilko I think this confirms that I can do it. It re-inforces the other answer. Thankyou. – therobyouknow Jul 10 '12 at 21:46
1

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.

rskar
  • 4,607
  • 25
  • 21
  • +1 This looks good - I'll have a good read tomorrow. Got a cold at the moment, need an earlyish night to rest. Thanks! – therobyouknow Jul 10 '12 at 21:42
  • I've read through it thanks @rskar. This has added an extra level of thinking around "When a "Reference" parameter is passed `ByVal`". It's worth bearing in mind, perhaps not right now for my problem but for future problems and certainly something to consider in debugging. If you could provide a C equivalent of the permutations you mention then that may help galvanise in my mind what is said. E.g. Would your passing a reference `ByVal` be the equivalent to a `const *` pointer in C? Thanks again, this is definitely useful material around the subject. – therobyouknow Jul 11 '12 at 09:31
  • P.S. thanks also for "By now, you probably already know you can pass in your Form as a ByVal parameter, and change its properties and fields without problem." - that's a bit like reflection whereby one can refer to members via their equivalent values in variables, giving us more flexibility to the code to manipulate them. – therobyouknow Jul 11 '12 at 09:33