2

次のようなコードがたくさんあり、インターフェイスに必要ないくつかのイベントを明示的に実装しています。

public class IMicrowaveNotifier {
  event EventHandler<EventArgs> DoorClosed;
  event EventHandler<EventArgs> LightbulbOn;
  // ...
}

public class Microwave : IMicrowaveNotifier {
  private EventHandler<EventArgs> _doorClosed;
  event EventHandler<EventArgs> IMicrowaveNotifier.DoorClosed {
    add { lock (this) _doorClosed += value; }
    remove { lock (this) _doorClosed -= value; }
  }

  private EventHandler<EventArgs> _lightbulbOn;
  event EventHandler<EventArgs> IMicrowaveNotifier.LightbulbOn {
    add { lock (this) _lightbulbOn += value; }
    remove { lock (this) _lightbulbOn -= value; }
  }

  // ...
}

これの多くが定型文であることがわかります。Rubyでは、次のようなことができます。

class Microwave
  has_events :door_closed, :lightbulb_on, ...
end

C#でこのボイラープレートを削除する同様の短い方法はありますか?


更新:例から非常に重要な部分を除外しました。つまり、実装されるイベントはインターフェイスの一部であり、明示的に実装したいと思います。これについて先に言及しなかったことをお詫びします!

4

4 に答える 4

10

これを試して:

public class Microwave {
    public event EventHandler<EventArgs> DoorClosed;
    public event EventHandler<EventArgs> LightbulbOn;
}

このコードは、C#のフィールドのようなイベント構文を利用しています。

フィールドのようなイベントをコンパイルする場合、コンパイラーはデリゲートを保持するためのストレージを自動的に作成し、イベントハンドラーをデリゲートフィールドに追加または削除するイベントのアクセサーを作成します。

C#1、2、および3では、このコードは上記のコードにコンパイルされます。C#4では、明示的なロックを使用しない機能的に同等のコードを取得します。どちらの方法でも、このタイプのコンシューマーを変更せずにこのショートカットを使用できます。

更新: 残念ながら、C#コンパイラでは、明示的なインターフェイスの実装にフィールドのようなイベントを使用することはできません。試してみると、次のコンパイルエラーが発生します。

イベントの明示的なインターフェイス実装では、イベントアクセサー構文を使用する必要があります

更新:明示的なインターフェースの実装でイベントアクセサー構文の使用が必要になるのは残念です。C#に、次のような自動的に実装されたフィールドのようなイベントを作成する機能が追加されたとしたら、それはちょっとクールでしょう。

event EventHandler<EventArgs> IAppliance.DoorClosed { add; remove; }

ただし、この構文は、既存のフィールドのようなイベント構文よりもすでに簡潔であり、インターフェイスメンバーが明示的に実装されている場合にのみ適用できます。私が思うに最も良いことは、コンパイラーが単にこれを実行できるようにすることです。

event EventHandler<EventArgs> IAppliance.DoorClosed;
于 2010-05-06T18:22:33.217 に答える
0

私はLockちょっと新しいので何をするのかわかりませんが、すべてのコントロールまたはそれらのイベントを呼び出しているものを1つのイベントに接続することができます。その場合は、ifステートメントを実行して、誰が送信しているかを確認してください。

見た目はかなりきれいに見えますが、それでもある程度の作業が必要だと思います。

于 2010-05-06T18:28:45.243 に答える
0

そのためのコードスニペットを作成し、ショートカットを使用します。if、for、foreach{tab}{tab}を使用する場合と同じです。

于 2010-05-06T18:36:43.840 に答える
0

gbogumilによって提案されたコードスニペットは、時間を節約します。あるいは、これを必要とする特定のインターフェースを定期的に実装している場合、抽象基本クラスを作成することは可能ですか?

于 2010-05-06T18:44:44.497 に答える