0

我理解错误的含义,但很奇怪我想不出任何原因,这是我的简化结构:

 public partial class mainForm : Form
{
    public mainForm()
    {
        InitializeComponent();
        IgnoreList = new SortedSet<string>();
        IgnoreListQueue IgnoreQueue = new IgnoreListQueue();
    }
    public class IgnoreListQueue
    {
        private Dictionary<string, int> myQueue;
        public void Add(string s)
        {
        }
        public IgnoreListQueue()
        {
            myQueue = new Dictionary<string, int>();
        }
        public bool contains()
        {}
        ~IgnoreListQueue()
        {
        }
    }
    public SortedSet<string> IgnoreList;
    public IgnoreListQueue IgnoreQueue;
    public int LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam)
    {
        //IgnoreList is fine here
        //IgnoreQueue is null here.
                    //Example:
                    // bool boo = IgnoreQueue.contains(some string);
    }
}

在 LowLevelKeyboardProc() 函数中,IgnoreQueue 被视为 null,当 VS 调试崩溃时,它确实显示 IgnoreQueue 为空指针。
由于我的程序挂钩键盘笔划,所以我无法在 LowLevelKeyboardProc() 函数中设置断点。但是,我能够在 mainForm() 构造函数中设置断点,并显示 IgnoreQueue 确实已初始化并在该点加载了一些数据。
请问有什么想法吗?

4

5 回答 5

1

这只是一个范围问题。在mainform () 构造函数中声明的 IgnoreQueue 在 LowLevelKeyboardProc() 方法中不可用。但是,IgnoreList 似乎在全局级别声明并在构造函数中初始化。

于 2012-10-11T11:38:22.283 回答
1

这一行:

IgnoreList = new SortedSet<string>();

初始化名为IgnoreList;的成员字段 但是这一行:

IgnoreListQueue IgnoreQueue = new IgnoreListQueue();

声明并初始化一个名为 的局部变量IgnoreQueue,它与同名的成员字段不同。成员字段仍将null在此之后。

由于您实际上想要初始化其他成员字段,因此您需要这样做:

IgnoreQueue = new IgnoreListQueue();
于 2012-10-11T11:41:29.487 回答
1

问题是您实际上并未初始化 mainForm 类的成员变量“IgnoreQueue”,而是在构造函数中创建了 IgnoreListQueue 的本地实例,该实例对其他成员函数不可用。

理想情况下,您的构造函数应该是这样的

 public mainForm()
    {
        InitializeComponent();
        this.IgnoreList = new SortedSet<string>();
        this.IgnoreQueue = new IgnoreListQueue();
    }
于 2012-10-11T11:45:40.130 回答
0
 public mainForm()
    {
        InitializeComponent();
        IgnoreList = new SortedSet<string>();
        IgnoreQueue = new IgnoreListQueue(); //no new declaration, this will set the public IgnoreListQueue you define later.
    }

建议在构造函数之前声明类字段,以提高可读性。你也应该考虑制作它们private,你不应该将实例变量声明为public.

于 2012-10-11T11:40:11.527 回答
0

您的问题归结为变量的范围,并且与 IgnoreQueue 有关。让我们看一下代码,看看发生了什么:

public IgnoreListQueue IgnoreQueue;
public mainForm()  
{
    InitializeComponent();
    IgnoreList = new SortedSet<string>();
    IgnoreListQueue IgnoreQueue = new IgnoreListQueue();
}

在您的构造函数中定义一个新变量 IgnoreQueue 并实例化它。尽管这与您的类上的属性具有相同的名称,但它不是同一个变量。相反,变量范围仅限于您的构造函数。这意味着当您稍后尝试使用该属性时,它为空,因此您的 NullReferenceException。

您可能还注意到,IgnoreList 没有在构造函数中重新定义,这就是为什么稍后会起作用的原因。解决此问题的最简单方法是删除构造函数中的 IgnoreListQueue 部分,使其与 IgnoreList 匹配:

IgnoreQueue = new IgnoreListQueue();

然而,更好的方法是使用this关键字,它可以帮助您立即发现问题。

public IgnoreListQueue IgnoreQueue;
public mainForm()  
{
    this.InitializeComponent();
    this.IgnoreList = new SortedSet<string>();
    this.IgnoreQueue = new IgnoreListQueue();
}
于 2012-10-11T11:46:00.587 回答