"Global" variables in vb.net


As you might know from my recent questions, I am converting Access fron-end apps to VB.Net apps (Windows-based currently), and I am mightily confused with the "scope" of variables compared to Access.

Let me explain: in Access, I always have forms with code-behind, usually an app-specific module with all needed logic in subroutines and functions, and a raft of generic routines / functions which are used in many apps. These generic sub's/functions are located in theme-related modules, and they can be called from anywhere: forms and modules.

In VB.net, I took one of my most complex app (not optimal as choice for the "VB.Net newbie" that I am, but it's the one which should be replaced first), and started to convert  the main form, the app-specific module and some of the generic modules. For the moment, I have kept all these in the same project, which is, I know, not how it should be, but gives me time to solve the myriad of other problems I encounter with VB.Net. I have defined the generic modules in Access as public modules in VB.net, and the app-specific module and the form behind-code as public subs within the form class.

But one thing is not clear to me at all: the scope of variables/objects. I don't know how to define (if it is possible) some variables/objects so that they can be accessed by any piece of code in the whole solution. I'm thinking of objects such as datasets, datatables, connections, even such mundane things such as the app's name. In order for variables/objects to be available to a module's subroutine, do they always have to be passed by the caller in the call ? As i have sometimes a hierarchy of calls (A calls B, which in turn calls C and D, the latter calls E), do I have to have a long list of params in every call so that the called routine can access the objects, or is there another way ?

Also I had some weird behavior with input and output variables (results of the called routine) passed in a call if I didn't mention a ByVal or ByRef. Are these absolutly mandatory in the called routines ? In some cases, I do not specify ByRef or ByVal in the called routines, and it works, in other cases it does not.

Can you give me some enlightening, clear pointers or doc about these themes ?

Thanks for help
bthouinIT Analyst and developerAsked:
Who is Participating?

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

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.

AndyAinscowFreelance programmer / ConsultantCommented:
This should be relevant:

Basically the scope of variables is pretty much what you are used to experiencing in Access.  Somethings (eg. application name) you can obtain from the app itself - so you don't need to pass them around.

>>A calls B, which in turn calls C and D, the latter calls E
If it is a common pattern of parameters you could consider making a custom class which contains these, so you only have to pass one parameter.  (Note you need to consider the future code maintenance and readability if you did do that).

ps.  Making variables global (or given too much scope) can be a bad design - just because it makes typing parameter lists shorter and easier isn't a good reason why.
you may define static member variables in a class which make them associated to the class rather than to a single instance of the class. that way these variables would be shared and have global scope.

see http://msdn.microsoft.com/en-us/library/zc2b427x.aspx for sample code.

note, doing so, it doesn't automatically beware of bad design (see comment of Andy). you should use static "shared" members only if they are singleton objects in your application. and the class to member relationship should be "has a" relationship (aggregation), for example class 'Company' "has a" static 'AllEmployees' array.

Jacques Bourgeois (James Burger)PresidentCommented:
The scope of simple variables is the same as it was in Access. I do not see why you are having problems with that.

- Public variables declared in a module are available in all the project.

- Variables declared with Dim (or Private) in a module or a class (a Form is a class) are visible only in that module or class.

- Variables declared in a method (Sub or Function) are visible only in that method.

- A small difference is that variables declared as Public in a class (Form) need to be handled through an instance of that class, that is a variable declared on that class.

- There is also a difference in the way a variable declared in a block (For...Next, While...End While, If...End If) is treated by the compiler. In .NET, it becomes a block variable, visible only in the block.


do they always have to be passed by the caller in the call

No, they don't. But yes, they should, as much as possible.

As Andy stated, Global variables are usually a bad design choice. They take up resources all the time the application is working, even if they are never used. If you have a bug with one of them, you need to look everywhere in the application, while for a local variable, you search for a problem is mostly limited to the method in which they are defined.

It takes getting used to it, but you can do almost everything without any global variable. There are always alternatives in .NET, sometimes hidden however, that you will learn as you go along.

Stuff such as the application name can be defined in the project's Properties window, and then recalled as a constant in the code through Application.ProductName.

Working with custom classes is a way to treat a group of values through only one variable. Dealing with only one variable makes it easy to pass the whole set of values as a parameter to methods that need it instead of having a list of 30 parameters to move around.

A Connection is usually a local variable. You open it, retrieve the data and close it. No need to keep a connection opened, there is a mechanism in the background that manage that for you (see Connection pooling).

Keeping a DataTable or a DataSet in a global variable is a very bad thing. These things use a lot more resources than a Recordset, so create them when needed and update and dump as soon as you are finished. Keeping them for a short time in memory will also help with concurrency (dealing with multiple users on the same data)

I write complex applications, and very rarely use global variables, except for debugging purposes.
Contrary to VBA, ByVal is the default in .NET. So, if you do not specify it, you get a ByVal/

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
bthouinIT Analyst and developerAuthor Commented:
Thanks guys for these very helpful comments. Now I will try to implement them :-)
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
.NET Programming

From novice to tech pro — start learning today.