[c#] C# - Winforms - Global Variables

I want some variables to be global across the project and accessible in every form. How can I do this?

This question is related to c# winforms global-variables

The answer is


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


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();
    }
}


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!!!


Or you could put your globals in the app.config


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
    }
}

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";

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to winforms

How to set combobox default value? Get the cell value of a GridView row Getting the first and last day of a month, using a given DateTime object Check if a record exists in the database Delete a row in DataGridView Control in VB.NET How to make picturebox transparent? Set default format of datetimepicker as dd-MM-yyyy Changing datagridview cell color based on condition C# Inserting Data from a form into an access Database How to use ConfigurationManager

Examples related to global-variables

What is the best way to declare global variable in Vue.js? How do I turn off the mysql password validation? How to declare Global Variables in Excel VBA to be visible across the Workbook How to create a global variable? global variable for all controller and views How to define global variable in Google Apps Script How to modify a global variable within a function in bash? Using a global variable with a thread Is it possible to use global variables in Rust? How to access global js variable in AngularJS directive