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 が null ポインターであることが実際に示されました。
プログラムがキーボード ストロークをフックするため、LowLevelKeyboardProc() 関数でブレークポイントを設定できませんでした。しかし、mainForm() コンストラクターでブレークポイントを設定することができ、IgnoreQueue が実際に初期化され、その時点でいくつかのデータがロードされたことを示しました。
アイデアはありますか?

4

5 に答える 5

1

この行:

IgnoreList = new SortedSet<string>();

と呼ばれるメンバ フィールドを初期化しIgnoreListます。しかし、この行:

IgnoreListQueue IgnoreQueue = new IgnoreListQueue();

という名前のローカル変数を宣言して初期化しますIgnoreQueue。これは同じ名前のメンバー フィールドとは異なります。この後もメンバー欄はnull続きます。

実際には他のメンバーフィールドを初期化したいので、代わりにこれを行う必要があります:

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

これは単なるスコープの問題です。mainform () コンストラクター内で IgnoreQueueが宣言されており、LowLevelKeyboardProc() メソッドでは使用できません。しかし、IgnoreList はグローバル レベルで宣言されているようで、コンストラクターで初期化されます。

于 2012-10-11T11:38:22.283 に答える
1

問題は、実際には mainForm クラスのメンバー変数 'IgnoreQueue' を初期化していないことですが、コンストラクターで IgnoreListQueue のローカル インスタンスを作成しているため、他のメンバー関数では使用できません。

理想的には、コンストラクターは次のようにする必要があります

 public mainForm()
    {
        InitializeComponent();
        this.IgnoreList = new SortedSet<string>();
        this.IgnoreQueue = new IgnoreListQueue();
    }
于 2012-10-11T11:45:40.130 に答える
0

問題は変数の範囲にあり、IgnoreQueue に関連しています。コードを見て、何が起こっているか見てみましょう。

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

コンストラクター内で、新しい変数 IgnoreQueue を定義してインスタンス化します。これはクラスのプロパティと同じ名前を共有していますが、同じ変数ではありません。代わりに、変数のスコープはコンストラクターに制限されます。これは、後でプロパティを使用しようとするとnullであるため、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 に答える
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 に答える