2

サブタイトル:EventHandlerListキーのタイプはオブジェクト以外のものにすることができますか?

EventHandlerに必要なキーを列挙型ストアとして使用したかったのです。

public enum EventKey
{
    OnBark, OnCry
}

public EventHandlerList EventList = new EventHandlerList();

public event ComplaintEventHandler OnBark
{
    add
    {
        EventList.AddHandler(EventKey.OnBark, value);
    }
    remove
    {
        EventList.RemoveHandler(EventKey.OnBark, value);
    }
}

var handler = EventList[eventKey] as ComplaintEventHandler;

>>

handler = null

結局のところ、それは機能しません。ただし、(に示すように)のように宣言されたキーを使用すると機能します。

static object EventKeyOnTap = new object();

いくつかのmscorlibのコードを読んだ後、問題next.key == key

private EventHandlerList.ListEntry Find(object key)
{
    EventHandlerList.ListEntry next = this.head;

    while (next != null && next.key != key)
    {
        next = next.next;
    }
    return next;
}

比較された両方のキーは私Enumのものですが、等しくありません!私はそれがobject起こっていることへのいくつかの暗黙のキャストから来ていると思います(リストに格納されているキーはタイプobjectです)が、そのような低レベルの概念には十分に流暢ではありません。

私の推測は正しいですか?

Enumのキーとしてを使用するための最良の方法は何EventHandlerListですか?

今のところ、キータイプとして自分EventHandlerListで作成します。Enum

今のところ、前述の等式比較の代わりに使用するコンストラクターを使用しEventHandlerListて、独自のコンストラクターを作成しました。Func<object, object, bool>

4

1 に答える 1

3

このコードを試してください。出力について説明できますか?

var bark1 = (object)EventKey.OnBark;
var bark2 = (object)EventKey.OnBark;

Console.WriteLine(bark1 != bark2);
Console.WriteLine(bark1.Equals(bark2));

はいの場合、なぜこの質問をしたのかわかりません。いいえの場合は、値の型参照の型、およびボクシングに注意する必要があります。

つまり、AddHandlerメソッドはパラメーターを受け入れるobjectため、呼び出し時にキー (値の型) がボックス化されます。

EventList.AddHandler(EventKey.OnBark, value);

同じ列挙キーでこのメソッドを 2 回呼び出すと、キーが 2 回ボックス化され、ヒープ内に 2 つの異なるオブジェクトが実際に作成されます。

next.key != keyこれが、このチェックインサイドメソッドが失敗する理由Findです (ヒープ内の 2 つの個別のオブジェクトのアドレスを比較します)。

EventHandlerList は封印されたクラスであるため、その内臓に影響を与えることはできませんが、独自のコードでは、より適切なチェックでこの状況を処理できます。

next.key.Equals(key)
于 2012-09-06T14:24:48.123 に答える