Passing Back a Parameter Value

In vb.net I have a form with the following Variable and Constructor ...

Public Class frmSelectAssembly

    Private intAssemblyId As Integer

    Public Sub New(ByRef intAssyId As Integer)

        intAssemblyId = intAssyId
        InitializeComponent()

    End Sub

I have the following code to instantiate and open the form ...

        Dim oForm As frmSelectAssembly
        Dim intAssemblyId As Integer

        oForm = New frmSelectAssembly(intAssemblyId)
        oForm.ShowDialog()
        MsgBox(intAssemblyId.ToString)

I set intAssemblyId in the Form's code before closing the form.  Since I passed it "By Reference", why doesn't MsgBox display the value that I set intAssembly?  How else can I pass a value back to the calling procedure?
LVL 1
Declan_BasileITAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Guy Hengel [angelIII / a3]Billing EngineerCommented:
that is not the way to work with "forms" to get back some value(s)

instead, make it a public property

Public Class frmSelectAssembly

    Private intAssemblyId As Integer
    

Property AssemblyId() As Integer
    Get
          Return intAssemblyId
    End Get
End Property

    Public Sub New(ByVal intAssyId As Integer)

        intAssemblyId = intAssyId
        InitializeComponent()

    End Sub

Open in new window


and the calling code shall be:
Dim oForm As frmSelectAssembly
        Dim intAssemblyId As Integer

        oForm = New frmSelectAssembly(intAssemblyId)
        oForm.ShowDialog()
        MsgBox(oForm.AssemblyId.ToString)

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Jacques Bourgeois (James Burger)PresidentCommented:
The problem with your code is that you pass the variable as intAssyId, but do not make any change to intAssyId from inside the constructor. When you assign it to intAssemblyId, you are making a copy. Changes made to that copy won't trigger back to intAssyId, so won't trigger back to your calling code.

Guy shows you the proper way to go, but forgot an important detail. There could also be a problem with taht approach if you are not careful. If you Close the Form from inside itself, it will be closed when you come back to your calling code, so you won't be able to retrieve oForm.AssemblyID.

The way to prevent that is to Hide the form instead of closing it. This way, the property value will still be available after the ShowDialog. After retrieving it, you will be able to retrieve it before closing it from the calling code:

oForm.ShowDialog()
MsgBox(oForm.AssemblyId.ToString)
oForm.Close()
Declan_BasileITAuthor Commented:
I understand that this may not be common practice, but is there a way to assign frmSelectAssembly's Private variable intAssemblyId to *reference* the same value of the Constructor Parameter intAssyId which references the same value as intAssemblyId of the calling procedure?  Is there some other way to get a reference to intAssemblyId of the calling procedure from anywhere in the code of the instance of frmSelectAssembly?
OWASP: Avoiding Hacker Tricks

Learn to build secure applications from the mindset of the hacker and avoid being exploited.

Jacques Bourgeois (James Burger)PresidentCommented:
No.

It's not a question of common practice, it's a question of how the language behave, which is directly controlled by the way values are handled in memory.

ByRef is valid only for parameters sent to a method, intAssyId in your case. When you lose that parameter, which happens when you hit the End Sub at the end of the New method, you lose the reference.

For value objects (an Integer is a value object), when you assign a variable to another variable (intAssemblyId), whether it is private, public or otherwise, you are making a copy. The copy is always distinct from the original.

The only way to do what you want is to do it indirectly, as we explained. What is wrong with that? It gives the same result as you would have had with a reference. If you need to keep the value after it is returned, simply call with the following code:

oForm.ShowDialog()
intAssemblyId = oForm.AssemblyId
oForm.Close()
MsgBox(intAssemblyId.ToString)
Declan_BasileITAuthor Commented:
I think it would be more simple if you could somehow just save the reference from within the constructor and directly set the calling procedure's variable within the form's code and wanted to know if that was an option.  I would prefer that over having to create a property, set the value of the property within the form, hide the form, reference the property in the calling procedure and then close the form.  Being a veteran Access developer, I'm still trying to understand the appeal of VB.net over Access when you could create a much simpler solution with a lot less overhead and complexity in much less time with Access.
Jacques Bourgeois (James Burger)PresidentCommented:
The main appeal is that it is buit in such a way that it prevents many common mistakes.

Passing values by reference is easy, but it can also easily lead to bugs that are hard to understand and fix. The more confined a variable is, the easier it is to understand what happened when there is a problem.

Access is designed for one thing: databases.
.NET is designed to do everything: databases, graphics, mobile, phone, web, services, dlls, you name it.

A tool as versatile as .NET is automatically more complex.

The second appeal of .NET, although one that does not appeal to everybody, is that it is designed first for professional programmers. Access is conceived to be an easy way to deal with databases, with VBA in the background for the occasional programmer.
Declan_BasileITAuthor Commented:
Thank you Guy for providing a way to do this, and thank you Jacques for adding the detail of only hiding the form until the property is referenced and then closing it and for the explanation of some of the benefits of vb.net.  Both were a great help and very much appreciated!
Declan_BasileITAuthor Commented:
FYI: It's documented here: that to declare a reference in c++ it's simply done as "int &var = <some-variable>;". The "&" is used to refer to the address rather than the value of the original variable and both variables reference the same value after this declaration is executed; however, I never found a vb.net equivalent to this.
Declan_BasileITAuthor Commented:
Declan_BasileITAuthor Commented:
Click Here  Sorry, it's the first time I've inserted a link and I'm not familiar with html.
Jacques Bourgeois (James Burger)PresidentCommented:
C++ can use a special type of variable called a pointer, which enables you to reference a specific address in memory.

Most security problems in Windows and operating system instabilities are caused by pointers. So they are not permitted in .NET.

You might have seen the term "managed code" popping here and there in the documentation. This means that instead of letting applications deal with pointers, as was the case before, in .NET pointers are managed only by the framework.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.