C# - 无法从事件处理程序访问全局变量

时间:2012-06-14 16:41:11

标签: c# variables reference null global

我有一个带有全局变量的Windows窗体应用程序 - 一个名为testPath的字符串。

此字符串用于保存路径 - 默认情况下为C:\temp\。当用户单击按钮时,将创建此目录(如果它尚不存在)。

如果用户想要更改路径的值,还有一个文本框控件。

在按钮的事件处理程序中,我尝试访问testPath并获得空引用。

我没有在任何地方更改testPath的值,除非我将其传入和传出文本框Control。

我做错了什么?全局变量如何在一秒内有内容,然后在之后它指向空引用?

以下是完整的代码:

public string testPath = @"C:\temp\";

public MainForm()
{
     //Windows Designer call
     InitializeComponent();

     //Show the testPath in the textBox (using Invokes)
     this.textBox1.Invoke(new MethodInvoker(delegate { this.textBox1.Text = testPath; } ));

     //here, testPath contains 'C:\temp\'
}

//Button "Click" handler
private void Button1Click(object sender, EventArgs e)
{
     //here, testPath contains a null reference!

     //If the user changed testPath in the textBox, we need to save it again
     this.textBox1.Invoke(new MethodInvoker(delegate { testPath = this.textBox1.Text; } ));

     //Create the path
     if(!Directory.Exists(testPath)) //If it does not exist already
     {
         Directory.CreateDirectory(testPath); 
     }

     //...Do something else

}

4 个答案:

答案 0 :(得分:8)

我建议将其设为常数:

const string testPath = @"C:\temp\";

这将导致任何尝试将值设置为标记为编译器错误。使用该值无需更改即可使用。


编辑以回应评论:

由于您要更改值,我建议将其重新设为属性:

private string _testPath = @"C:\temp\";
private string testPath 
{ 
    get { return _testPath; }
    set
    {
        _testPath = value;
    }
}

然后,您可以在行_testPath = value;上设置断点,并在调试器中查看将此设置为null的确切内容。一旦纠正,我会建议修复命名以匹配标准的.NET命名约定。

答案 1 :(得分:3)

我会尝试将字段testPath标记为只读,并遵循编译错误。

这是关于const和readonly之间差异的a tutorial

编辑您可以查看为表单加载事件实现自定义处理程序并检查其中的状态。您还可以在构建对象时使用F10,因为您正在处理表单加载事件,并且正在处理用户输入。请记住,当刚刚进入该函数时,所有变量在开始大括号上显示为未初始化。您必须至少执行一次该功能才能看到它们。使用引脚在文本编辑器中密切关注变量。

答案 2 :(得分:1)

<强>更新: 我不确定你为什么需要这个公共变量。如果你只是想用一些初始值初始化控件,比如“C:\ temp \”&amp;用户可以根据需要进行编辑。如果是这种情况,请在设计视图中打开表单,右键单击文本框&gt;去物业。在属性窗口中,将Text属性更改为“C:\ temp \”,完成此操作后,将使用“C:\ temp \”初始化文本框。在事件处理程序中,您只需编写

即可
private void button1_Click(object sender, EventArgs e)
{
     if (!Directory.Exists(this.textBox1.Text.Trim()))
        {
            Directory.CreateDirectory(this.textBox1.Text.Trim());
        }

}

<强>原始: 初始化Form但在单击按钮之前,testPath变量将被修改为null。因为它是一个公共变量,所以可以访问它。也是从课外修改过来的。

重现此问题的一种简单方法 - 在“程序”类中&gt;主要方法

[STAThread]
static void Main()
{
   Form1 obj = new Form1();
   obj.testPath = null;
   Application.Run(obj);
}

建议: 1.使testPath保持常量或只读以确定它是否被修改。 2.如果您不需要公开访问说明符,请将访问说明符更改为私有。

答案 3 :(得分:0)

我建议您不要在按钮点击事件范围之外声明路径,而是在方法内声明它。

像这样:

private void Button1Click(object sender, EventArgs e) 
{ 
     string testPath = @"C:\temp\"; 

     //Create the path if it does not exist      
     if(!Directory.Exists(testPath))      
          Directory.CreateDirectory(testPath);       
}