3

次のコードをコンパイルできません。

コンパイル エラー CS0079: イベント 'CustomEvent' は、+= または -= の左側にのみ表示できます

if (CustomEvent != null)   //CS0079
    CustomEvent(null, null);  //CS0079

どうすればこれを機能させることができますか?

私の実装は次のようなものです:

public delegate void EventHandler(object sender, EventArgs e);  
public static event EventHandler CustomEvent
{
    add    { CustomEvent += value; }
    remove { CustomEvent -= value; }
 }
private static void Func()
{
    if (CustomEvent != null)      //CS0079
        CustomEvent(null, null);  //CS0079
}
4

2 に答える 2

6

あなたの編集は再帰呼び出しを示しています: カスタム イベントを宣言しています。これは、バッキング フィールドを提供することを意味します例えば:

private static EventHandler customEvent;
public static event EventHandler CustomEvent
{
    add    { customEvent += value; }
    remove { customEvent -= value; }
 }
private static void Func()
{
    var tmp = customEvent;
    if (tmp != null) tmp(null, null);
}

ここでは、イベント( ) ではなく、フィールド( )Funcについて言及していることに注意してください。customEventCustomEvent

ただし、これはフィールドのようなイベントとしては単純であるほど優れています (スレッドセーフ)。

public static event EventHandler CustomEvent;
private static void Func()
{
    var tmp = CustomEvent;
    if (tmp != null) tmp(null, null);
}

フィールドのようなイベントはeventキーワードを使用しますが、アクセサーを省略します: コンパイラーは多くのボイラープレートを追加します (バッキング フィールドとスレッドセーフな追加/削除の実装)。さらに、イベント名(宣言型から) を介してバッキング フィールドにアクセスできるため、行がどのように機能するかが分かりvar tmp = CustomEvent;ます。

また、静的イベントには十分注意してください。これらは、誤って多くのオブジェクトを存続させる優れた方法です。

于 2012-12-22T07:59:45.390 に答える
3

現在の型で宣言されたフィールドのようなイベントである場合にのみ、イベントをテスト/呼び出すことができます。したがって、これを引き起こすシナリオは 2 つあります。

  1. フィールドのようなイベントではありませんが、カスタムadd/removeアクセサーがあります。この場合、カスタム コードだけがデリゲートの格納方法を知っています。

  2. 現在の型では宣言されていませんが、基本型または関連のないオブジェクト内にあります。この場合、通常はOnCustomEventメソッドを介して、イベントを呼び出すために宣言型を取得する必要があります。基本型の場合、このメソッドを作成するのが慣例となり、protected virtualサブクラスがイベントを呼び出してイベントフックできるようになります。override


(コメント)

ケース1のようです。ただし、この問題を解決するために何をすべきかわかりません。

カスタムのadd/がある場合、それを呼び出す方法は実装によって異なります ( /が表示されremoveていれば詳細を説明できます) が、2 つの一般的な実装を見てみましょう。addremove

1a: バッキング デリゲート:

private EventHandler someEvent;
public event EventHandler SomeEvent
{
    add { someEvent += value; }
    remove { someEvent -= value; }
}

この場合、「呼び出し」の実装は次のようになります。

if(someEvent != null) someEvent(this, EventArgs.Empty);

または、特に用心深い場合:

var handler = someEvent;
if(handler != null) handler(this, EventArgs.Empty);

1b: an EventHandlerList(まばらなイベントに使用):

private static readonly object SomeEventKey = new object();
public event EventHandler SomeEvent
{
    add { Events.AddHandler(SomeEventKey, value); }
    remove { Events.RemoveHandler(SomeEventKey, value); }
}

この場合、呼び出しの実装は次のようになります。

var handler = (EventHandler)Events[SomeEventKey];
if(handler != null) handler(this, EventArgs.Empty);
于 2012-12-21T07:36:19.270 に答える