question

William-8598 avatar image
0 Votes"
William-8598 asked William-8598 commented

Visual Studio 2019 Form1.cs C# Global Variable

I need to share a variable anywhere in Form1.cs.
Tried using example, https://social.msdn.microsoft.com/Forums/windows/en-US/536b644b-bc4b-42c4-8ad5-2458553c3cd3/how-to-make-certain-variables-global-to-all-forms-c?forum=winforms, but receive the following error;

CS0122 : 'Variables.ChartArray' is inaccessible due to its protection level

Can you share a variable anywhere in Form1.cs?
If so, how?

windows-forms
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

From the error message shown, you just need to declare the member variable as public.

2 Votes 2 ·

Instead of thinking in terms of files, as in Form1.cs, you need to think in terms of classes. The Form1.cs file has the Form1 class and the error message is the result of trying to access a Form1 class member from a different class and once you understand that you can understand the previous comment from DavidLowndes-6766.

0 Votes 0 ·
karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered William-8598 commented

Consider a Singleton class

 public sealed class ApplicationSettings
 {
     private static readonly Lazy<ApplicationSettings> Lazy = 
         new Lazy<ApplicationSettings>(() => new ApplicationSettings());
    
     /// <summary>
     /// Access point to methods and properties
     /// </summary>
     public static ApplicationSettings Instance => Lazy.Value;
     public char[] ChartArray { get; set; }
 }

Usage

Read the array

 ApplicationSettings.Instance.ChartArray

Update

 char[] someArray = new[] { 'c', 'd', 'e' };
 ApplicationSettings.Instance.ChartArray = someArray;


Or

 ApplicationSettings.Instance.ChartArray[0] = 'a';
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thanks you for responding.

Your solution is elegant and the only solution so far that works for me.

0 Votes 0 ·
cooldadtx avatar image
0 Votes"
cooldadtx answered William-8598 commented

There is really no such thing as a global variable in C#. You can however have a static (shared) value contained in a class. If that class is itself static (shared) then this is about as close to a global variable as you can get. But it is generally not recommended that you do this. It generally indicates you have a design problem. Really the same thing applies to any language that allows globals. Global variables are almost always the wrong solution. There are a couple of well defined cases where such a design may make sense (singletons, for example) but even then they should be rarely used and only if there is not a better option. You can google for the whys.

Back to your question, to expose a value from a class make it public.

public class ParentForm : Form
{
   //Anybody with access to the instance can read or write this value
   public string Title { get; set; }
}


To share across other forms you would simply pass an instance of the desired ParentForm around.

public class ChildForm : Form
{
    public ParentForm { get; set; }

    private void SomeFunction ()
    {
        //Assuming ParentForm has already been set...
        string parentTitle = ParentForm.Title;
    }
}


If you need to access the type without passing an instance around then use a singleton ideally.

public class ParentForm : Form
{
    //Note that normally you make the ctor private but that won't work with a Form
    public ParentForm ()
    {
        ...
        Default = this;
    }

    public static ParentForm Default { get; private set; }
}


By marking the member as static it is now accessible without an instance

string title = ParentForm.Default.Title;


If your type only contains static members then you don't really need an instance and can make the entire type static which saves an allocation.

public static class DataManager
{
    public static DbConnection CreateConnection () { ... }
}

//Somewhere else
using (var conn = DataManager.CreateConnection())
{
}

· 9
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Ok if global variable are bad, not sure why, what is the right solution?
If the user push button1 and is ask to enter a count. Then the user push button2 which will count down from the count defined in buttom1, how does the button2 get the count from button1?

0 Votes 0 ·

Are the buttons on different forms? Are both forms shown at the same time or does the user enter a count and then click a button that opens the new form and starts counting down? Is there any additional data that is going to be needed besides a simple counter?

0 Votes 0 ·

Both buttons are on the same form, shown at the same time.

namespace TestOfVariable
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

     private void button1_Click(object sender, EventArgs e)
     {
         double[] ChartArray = new double[60];

     }

     private void button2_Click(object sender, EventArgs e)
     {
         double[] MeasgDoubleDelta = new double[60];
         MeasgDoubleDelta = ChartArray;
     }

        
 }

}The "ChartArray" in button2_Click produces an error; CS0103: The name'ChartArray' does not exist in the current context

0 Votes 0 ·
Show more comments