Reputation: 1398
I'm used to scripting languages. PHP, Javascript etc. and I've written a few relatively simple Java and C# apps. This is a question I've repeatedly needed an answer for, and I imagine I'm not the only one.
Let's say I'm in Javascript.
I have function A(), called by the GUI, which retrieves some value.
Function B(), also called by the GUI, requires that value, but function B() is going to be called an arbitrary number of times, an arbitrary length of time after A().
I don't want A() to recalculate the value every time.
An example is logon credentials. A() asks for a username, and B() uses that value to append to a log every time it is called.
For this I would probably just use a global variable.
Now, C#. No global variables! How am I supposed to do this?
Edit: Enjoying the answers, but there are a lot of "try not to use globals" comments. Which I do understand, but I'd like to hear the alternative patterns for this requirement.
Upvotes: 9
Views: 8822
Reputation: 18815
Firstly, always ask yourself if you really need to have a global, often you won't. But if you really have to have one...
The best way to do this is to have a static property on some sensibly named class, it effectively becomes your global variable
public class Credentials
{
public static string Username {get;set;}
}
//...somewhere in your code
Credentials.Username = "MyUserName";
EDIT:
A couple people here have said the blanket statement that Global Variables are bad, and I do agree with this sentiment, and it would appear that the designers of C# also agree as they are simply not available.
We should however look at the reasons why Globals are bad, and they are mostly regarded as bad because you break the rules of encapsulation. Static data though, is not necesarrily bad, the good thing about static data is that you can encapsulate it, my example above is a very simplistic example of that, probably in a real world scenario you would include your static data in the same class that does other work with the credentials, maybe a Login class or a User class or whatever makes sense to your app.
Upvotes: 4
Reputation: 13214
This is not a good practice, but if you really need it, there is a number of ways:
Upvotes: 5
Reputation: 52123
I'd say you should probably use a Singleton Pattern.
If you're going for a multithreaded application then you need to also make sure accesses to the properties of the instance of the singleton are threadsafe.
As always please think carefully about introducing any kind of global in your application but don't be affraid to use it. A lot of things are indeed globals, like the App.Settings for example without having anything "bad" in them.
This article on MSDN explains how to correctly create a singleton in c#.
Upvotes: 1
Reputation: 25677
Function A would be part of a class (call it C). Function A could then store the logon credentials and provide a function (or in C#, a property) to obtain the credentials. When they are required, you can simply use the property to obtain the stored credentials and pass them into Function B (on a different class).
class C
{
public void functionA()
{
credentials = obtainCredentials;
}
private LogonCredentials _logonCredentials = null;
public LogonCredentials logonCredentials
{
get { return _logonCredentials; }
}
}
class D
{
public void functionB(LogonCredentials credentials)
{
//do stuff
}
}
///other stuff
///other function ...
...
instanceC = C();
instanceC.functionA();
///more stuff here
instangeD = D();
instanceD.functionB(instanceC.logonCredentials);
Upvotes: 0
Reputation: 39480
In C#, one of the ways to get behavior similar to global variables is to use static class methods and class variables. Static class methods and variables have a single instance in C#, and are somewhat akin to global variables in other languages.
That said, for your problem, it sounds much more like a design problem. C# is very focused on Object Oriented Design; I'd suspect for the problem you've given that a better OOD would resolve your problem.
Upvotes: 0