I have read the article Global Variables Are Bad and i have some question:
Supposed i have several variables for example:
int loops
This variable should be accessible from anywhere in the code so i have 2 options:
define this variable as global inside my main form
define class:
public static class Loops
{
public static int loops {get; set;}
}
What's the right way to do it and what is the differences between the both ?
A public static variable inside a static class is like your old global variable. The only difference is that you always need to specify the class name to access its value. It is available in every part of your code that has a reference to the assembly and namespace where that static class is contained. And there is just one value for that variable.
A public instance variable inside a form is a variable that exists only if you build an instance of your form and it is a different variable from any other variable in other instances of the same form
for example
public static class GlobalAppVariables
{
public static int loops {get; set;}
......
}
in othe part of your project or other assemblies with correct reference to the defining assembly
for(int x = 0; x < GlobalAppVariables.loops; x++)
instead with a global public variable inside a form class
public class MyForm : Form
{
public int loops {get; set;}
}
to use that variable you need an instance of the MyForm class, and if you have two instances, you have two different variables.
MyForm f = new MyForm();
f.loops = 15;
for(int x = 0; x < f.loops; x++)
......
MyForm f1 = new MyForm();
f1.loops = 100;
.....
From an OOP point of view, and for every non trivial programs you should try hard to avoid global variables. But that's is theory, in real world with real constraints (performance, time to develop, programmer expertise, nature of the task and other considerations) it is not always possible to completely avoid them.
My suggestion is to confine them in a well understood class with explicit property backing fields to allow the maximum of flexibility in case of future changes. Of course, documentation plays a key role here
Assuming you have a project with business logic, UI layer will consume it and have a reference to it. If you business logic is dependent on loops in your form class then not only won't you be able to add a cyclic reference but it is not a good idea for BL to be directly dependent on UI, if we talk about OOP here.
Second option is good enough if you keep all configurations in your, say, Configuration class, but changing it means recompiling the solution.
Application Configuration File is the right way to go for application configurations:
Add an Application Configuration File item to your project (right click project > add item). This will create a file called app.config in your project.
Edit the file by adding entries like <add key="loops" value="10" /> within the <appSettings> tag.
Add a reference to the System.Configuration dll in your project, and reference the loops setting in the config using ConfigurationManager
like:
ConfigurationManager.AppSettings["loops"]
It depends my friend, seems that for your first option its not global if you want to be used every where in the form, in such a case the form becomes your context. While using a static variable within a class (public and NOT Nested class) is truly a global variable that should be used carefully and has a good purpose to be there.
The article you referenced applies to C++. In C++ a global variable is a variable that is declared outside of a class. In C#, however, a global variable is a variable declared public inside of a class (as a variable cannot exist outside of a class or a struct). The equivalent of avoiding these global variables would be to declare them as properties with appropriate scope applied to the get and set accessors.
Declaring a global variable does not respect any of the base priciples of OOP; the whole program can read it and maybe modify it( unless that is what you want ). The solution is to make a class with private static int loops {get; set;}
Related
Is it possible that different objects of different classes can use one shared item among themselves (e.g for providing some information on the fly) or better a means of communication between different objects of two different classes ?
Class Base
{
public static string SomeThing = "Shared With All";
}
Class Der1 :Base
{
public void DoSomeThing()
{
SomeThing = "SomeThing Goes in here...";
}
}
Class Der2 :Base
{
public void DoSomeThingElse()
{
Console.WriteLine"(SomeThing);
}
}
....
{
Der1 dr1 = new Der1();
dr1.DoSomeThing();
Der2 dr2 = new Der2();
dr2.DoSomeThingElse(); //shows 'SomeThing Goes in here...'
}
If it helps more, I am trying to create a designer of some kind and so I need to get track of all controls and their associations on the designer. Actually there are only two objects at the moment (one called transaction and the other is called place, different places can be associated with different transactions, and this association is done by the user clicking on one place and pointing to the other transactions (have you seen Proteus? something like that).
So this approach will help me know which object is referring which other object and thus and association between the two can be easily spotted and saved.
The static field isn't really inherited in the same way as normal fields are. There's still just one static field, Base.SomeThing. Both of your derived classes are referring to the same field: if anything changes Base.SomeThing, everything that accesses that field will see the change.
Yep, you've invented a global variable :) It is also almost always a sign of bad design. Try solving your task differently.
It is possible, but think carefully about communicating in this way inside the class. There is no good way to account for concurrency issues and very hard to debug if the value is set multiple places.
You can either use static var's or share stuff using setter and getter. These are basic operators in OOP.
A static field belongs to the class that declares it. Any subclasses of that class gets access to that one static field.
There are some caveats here. Declaring a static variable on a Generic class means that one copy of that variable exists for each closed type of that generic. Here's an example to clarify
public class StaticGenericTest<T>
{
private static int count=0;
public StaticGenericTest()
{
count++;
}
}
If you instantiate a StaticGenericTest<int> and a StaticGenericTest<string> they would have different values for count. However a subclass of StaticGenericTest<int> would share count with all other subclasses of StaticGenericTest<int>.
Also you'll get funny behavior using the ThreadStatic attribute (because you'll get one copy of count per thread) and/or static constructors.
As someone mentioned, Static fields are global state and should be protected as such and used with caution.
I have a mainForm variable that is used nearly everywhere in my program. I'd like to be able to reference to this variable without having to type the name of the class that holds this variable (i.e. instead of Global._mainForm, I should be able to just type _mainForm to access this variable anywhere within the same namespace).
What is the best way to accomplish this?
Anytime I see a global anything I get worried, so I would reconsider how your program is architected. You can almost always get away without having a globally accessible object. Although there are legitimate reasons to have a globally accessible object, usually I try to stay away from them.
From the little information you've given, you might be able to use events to talk to the main window instead of directly accessing it.
If you do have real need for a globally accessible object then you could do something like this
Note: In the code below everything is static, conversely you could create a special static class that holds a reference to the instance of the class you're really interested in. But there is no way that I'm aware of to hold a global reference that is outside of all namespaces to an instance of an object.
using Bar = ProbablyAReallyBadIdeaToHaveAGlobalAnythingButHeyWhyNot.TestClass;
namespace ProbablyAReallyBadIdeaToHaveAGlobalAnythingButHeyWhyNot
{
public static class TestClass
{
public static int TestFoo { get; set; }
}
}
namespace Foo.SomeOtherNamespace
{
class MyClassThatDoesStuff
{
public void DoStuff()
{
Bar.TestFoo = 123;
}
}
}
You can't accomplish this in C#.
Namespaces are simply part of the type name of a class. Lexically, you can think of a namespace as containing only other namespaces and classes.
Classes may contain fields, functions, events, properties, nested classes, etc., but not nested namespaces.
Therefore there is no way to to define a symbol in a namespace outside of class that aliases or refers to a symbol contained in a specific class.
When resolving the reference to the variable name _mainForm, the only place that it does not require additional qualification is from within the scope of the class that it is defined in.
If you are in a namespace scope that is the same as as the class that defines _mainForm (and _mainForm is a static instance), then you only need access it by qualifying it with the class name. Otherwise you will require additional namespace qualification, or perhaps trickery with a using directive. But outside of the containing class, you will always require a qualification of some kind to access _mainForm.
See http://en.csharp-online.net/ECMA-334:_10.7_Scopes for excruciating detail.
The only way I can see, in C#, for every class in a namespace to be able to directly address the same variable is by defining the variable as static in a base class used by all other classes in the namespace. Since static variables can be addressed as local variables within the class (or classes inheriting from) they are defined in, the variable will be available without class qualifications.
Can't say it is a good idea, but that's not what you asked ...
I have two objects that I will be mainly use inside of single class. I will initialize them at the beginning and use them throughout the life of the program. Now, my question is that if I should just create them as global variables and access them anywhere in the code (in side of single class) or I should create them as local variables and pass them as parameters to other functions. I just want to see what would be the best programming practice.
I am using C#.
Thanks.
In general you should avoid global variables. If it will be practical, I recommend keeping them as locals and passing them as parameters to your functions.
As Josh pointed out, if these variables are only used inside a single instance of the class, then you should just make them private (or protected) members of that class and be done with it. Of course, then they could only be passed in as parameters to other methods with the same access level (IE, private).
Alternatively, you may consider using the Singleton Design Pattern, which is slightly cleaner (and preferable) to using globals.
If the scope of the objects is the lifetime of the class they are instantiated in, then they should be private member variables.
If they do not maintain state themselves, then you should make them static classes.
You should still pass them around as variables, or at least create property accessors to get at the backing field. This way you can change implementation details without blowing up your code.
SOLID design principles are a good place to start when thinking about these things.
I have two objects that I will be
mainly use inside of single class. I
will initialize them at the beginning
and use them throughout the life of
the program.
This sounds like a perfect time to use a private static readonly variable. These can be initialized in their declaration, or you can make a static constructor to initialize them.
The fact that you are only referencing these objects within a single class is key point. There are other better ways to do things if these objects are ever needed outside of the single class.
If the objects will be the same for every instance of the class then
static const double PI = 3.14158;
You should generally use accessor methods (e.g. getters and setters) and keep your internal variables private. This way the rest of your code, outside of your class, is not dependent on your actual variables.
See this tutorial.
If your class is dependent on these 2 objects then they should probably be members on the class itself. Something like this (where A is the class you are talking about and B is one of the objects you initialize:
public class A
{
private B _b;
public A(B b)
{
_b = b;
}
public void DoSomething()
{
//do something with _b;
}
private void DoSomethingElse()
{
//do something else with _b;
}
}
In this example A is dependent on B (so you pass your instance of B into A's constructor or through some Dependency Injection framework). It wouldn't make a lot of sense for every method on class A to need a parameter of type B to be passed to it.
I think in this case you should ask what makes more sense. Is there some kind of relationship between the 2 objects and the new class. Also, how often are they used in the class.
Generally, If only a couple of methods use the objects, pass them around otherwise, instantiate them as class level variables (possibly using private static readonly as Jefferey suggests) and use them in the class. Making the code more readable should be your goal here.
I want some variables to be global across the project and accessible in every form. How can I do this?
yes you can by using static class.
like this:
static class Global
{
private static string _globalVar = "";
public static string GlobalVar
{
get { return _globalVar; }
set { _globalVar = value; }
}
}
and for using any where you can write:
GlobalClass.GlobalVar = "any string value"
The consensus here is to put the global variables in a static class as static members. When you create a new Windows Forms application, it usually comes with a Program class (Program.cs), which is a static class and serves as the main entry point of the application. It lives for the the whole lifetime of the app, so I think it is best to put the global variables there instead of creating a new one.
static class Program
{
public static string globalString = "This is a global string.";
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
And use it as such:
public partial class Form1 : Form
{
public Form1()
{
Program.globalString = "Accessible in Form1.";
InitializeComponent();
}
}
Or you could put your globals in the app.config
You can use static class or Singleton pattern.
One way,
Solution Explorer > Your Project > Properties > Settings.Settings. Click on this file and add define your settings from the IDE.
Access them by
Properties.Settings.Default.MySetting = "hello world";
public static class MyGlobals
{
public static string Global1 = "Hello";
public static string Global2 = "World";
}
public class Foo
{
private void Method1()
{
string example = MyGlobals.Global1;
//etc
}
}
If you're using Visual C#, all you need to do is add a class in Program.cs inheriting Form and change all the inherited class from Form to your class in every Form*.cs.
//Program.cs
public class Forms : Form
{
//Declare your global valuables here.
}
//Form1.cs
public partial class Form1 : Forms //Change from Form to Forms
{
//...
}
Of course, there might be a way to extending the class Form without modifying it. If that's the case, all you need to do is extending it! Since all the forms are inheriting it by default, so all the valuables declared in it will become global automatically! Good luck!!!
They have already answered how to use a global variable.
I will tell you why the use of global variables is a bad idea as a result of this question carried out in stackoverflow in Spanish.
Explicit translation of the text in Spanish:
Impact of the change
The problem with global variables is that they create hidden dependencies. When it comes to large applications, you yourself do not know / remember / you are clear about the objects you have and their relationships.
So, you can not have a clear notion of how many objects your global variable is using. And if you want to change something of the global variable, for example, the meaning of each of its possible values, or its type? How many classes or compilation units will that change affect? If the amount is small, it may be worth making the change. If the impact will be great, it may be worth looking for another solution.
But what is the impact? Because a global variable can be used anywhere in the code, it can be very difficult to measure it.
In addition, always try to have a variable with the shortest possible life time, so that the amount of code that makes use of that variable is the minimum possible, and thus better understand its purpose, and who modifies it.
A global variable lasts for the duration of the program, and therefore, anyone can use the variable, either to read it, or even worse, to change its value, making it more difficult to know what value the variable will have at any given program point. .
Order of destruction
Another problem is the order of destruction. Variables are always destroyed in reverse order of their creation, whether they are local or global / static variables (an exception is the primitive types, int,enums, etc., which are never destroyed if they are global / static until they end the program).
The problem is that it is difficult to know the order of construction of the global (or static) variables. In principle, it is indeterminate.
If all your global / static variables are in a single compilation unit (that is, you only have a .cpp), then the order of construction is the same as the writing one (that is, variables defined before, are built before).
But if you have more than one .cpp each with its own global / static variables, the global construction order is indeterminate. Of course, the order in each compilation unit (each .cpp) in particular, is respected: if the global variableA is defined before B,A will be built before B, but It is possible that between A andB variables of other .cpp are initialized. For example, if you have three units with the following global / static variables:
Image1
In the executable it could be created in this order (or in any other order as long as the relative order is respected within each .cpp):
Image2
Why is this important? Because if there are relations between different static global objects, for example, that some use others in their destructors, perhaps, in the destructor of a global variable, you use another global object from another compilation unit that turns out to be already destroyed ( have been built later).
Hidden dependencies and * test cases *
I tried to find the source that I will use in this example, but I can not find it (anyway, it was to exemplify the use of singletons, although the example is applicable to global and static variables). Hidden dependencies also create new problems related to controlling the behavior of an object, if it depends on the state of a global variable.
Imagine you have a payment system, and you want to test it to see how it works, since you need to make changes, and the code is from another person (or yours, but from a few years ago). You open a new main, and you call the corresponding function of your global object that provides a bank payment service with a card, and it turns out that you enter your data and they charge you. How, in a simple test, have I used a production version? How can I do a simple payment test?
After asking other co-workers, it turns out that you have to "mark true", a global bool that indicates whether we are in test mode or not, before beginning the collection process. Your object that provides the payment service depends on another object that provides the mode of payment, and that dependency occurs in an invisible way for the programmer.
In other words, the global variables (or singletones), make it impossible to pass to "test mode", since global variables can not be replaced by "testing" instances (unless you modify the code where said code is created or defined). global variable, but we assume that the tests are done without modifying the mother code).
Solution
This is solved by means of what is called * dependency injection *, which consists in passing as a parameter all the dependencies that an object needs in its constructor or in the corresponding method. In this way, the programmer ** sees ** what has to happen to him, since he has to write it in code, making the developers gain a lot of time.
If there are too many global objects, and there are too many parameters in the functions that need them, you can always group your "global objects" into a class, style * factory *, that builds and returns the instance of the "global object" (simulated) that you want , passing the factory as a parameter to the objects that need the global object as dependence.
If you pass to test mode, you can always create a testing factory (which returns different versions of the same objects), and pass it as a parameter without having to modify the target class.
But is it always bad?
Not necessarily, there may be good uses for global variables. For example, constant values (the PI value). Being a constant value, there is no risk of not knowing its value at a given point in the program by any type of modification from another module. In addition, constant values tend to be primitive and are unlikely to change their definition.
It is more convenient, in this case, to use global variables to avoid having to pass the variables as parameters, simplifying the signatures of the functions.
Another can be non-intrusive "global" services, such as a logging class (saving what happens in a file, which is usually optional and configurable in a program, and therefore does not affect the application's nuclear behavior), or std :: cout,std :: cin or std :: cerr, which are also global objects.
Any other thing, even if its life time coincides almost with that of the program, always pass it as a parameter. Even the variable could be global in a module, only in it without any other having access, but that, in any case, the dependencies are always present as parameters.
Answer by: Peregring-lk
Ok after reading this article and also some of the examples I am still not clear on what global variables mean. So its say private variables in your class are global?
http://www.c2.com/cgi/wiki?GlobalVariablesAreBad
So can someone explain this to me in simple terms the context. Does this mean even private fields at the top of your class? I'm not clear on the definition of a "global variable" so that I can distinguish if I'm doing something "bad" in my classes.
In C# an example of a global variable would be a public static variable on a public class. The entire program could read/write to it and it would be shared across threads as well.
A private field in your class would generally be called a "class level variable". It isn't global to your application because only your class has access to it.
A global variable is a variable that anything in your program can access no matter what scope it's in.
An example of a global variable would be something like the Application object in ASP.Net (a public static instance of an HttpApplication class). Any object, at any time, in any code-behind file, can have access to the Application object to look for that value. Generally, storing values to the Application object is a bad idea unless you really know what you're doing, for all the reasons mentioned in the article that you linked.
No. Global variables are variables which are available to your entire program. Private member variables are effectively the opposite of global variables. In C/C++ a global variable would be one which is declared outside of a function or class declaration. In C++ and Java, a public static variable which is not constant would also be considered to be a global variable, since the entire program can access it.
In C# there really isn't anything that could be called a "global" variable. The closest would be a public static variable; something that is available to all parts of the program at any time.
Basically there are other mechanisms that can lead to global variables introduction:
AppDomain.GetData/AppDomain.SetData pair - Gets/Sets the value stored in the current application domain for the specified name which is accessible either from other application domains.
Thread.GetData/SetData pair - Gets/Sets the value from the specified slot on the current thread, within the current thread's current domain.
As the arcticle states it is better to avoid them.
I thinks Varialbes defined in the top of class with "DIM" still class scope and not Global, but if they defined as "PUBLIC" on top of class or "PUBLIC" in "MODULE" they could be "GLOBAL" , the GOOD you can access these variables form the ALL solution, the BAD , they will stay in MEMORY..