C#でイベントを転送するクラスを使用しています。コードのオーバーヘッドを少なくする方法があるのではないかと思っていました。
これが私がこれまでに持っているものの例です。
class A
{
public event EventType EventA;
}
class B
{
A m_A = new A();
public event EventType EventB;
public B()
{
m_A.EventA += OnEventA;
}
public void OnEventA()
{
if( EventB )
{
EventB();
}
}
}
クラスAは元のイベントを発生させます。クラスBはそれをEventB(本質的に同じイベント)として転送します。クラスAは他のモジュールから隠されているため、EventAに直接サブスクライブすることはできません。
私がやろうとしているのは、イベントを転送するためのクラスBのコードオーバーヘッドを減らすことです。通常、クラスBのイベントは実際には処理されません。また、いくつかの異なるイベントがあるため、多くのOnEventを作成する必要があります()イベントの転送にのみ役立つクラスBのメソッド。
なんらかの方法でEventAをEventBに自動的にリンクすることは可能ですか?
class B
{
A m_A = new A();
public event EventType EventB;
public B()
{
m_A.EventA += EventB; // EventA automatically raises EventB.
}
}
ところで、C#2.0コンパイラを使用しています。
絶対に:
class B
{
private A m_a = new A();
public event EventType EventB
{
add { m_a.EventA += value; }
remove { m_a.EventA -= value; }
}
}
つまり、EventBサブスクリプション/サブスクリプション解除コードは、サブスクリプション/サブスクリプション解除要求をEventAに渡すだけです。
ただし、これでは、EventBをサブスクライブしたサブスクライバーに対してイベントを発生させることはできませんjust。これは、誰かの住所をマスマーケティング会社に直接渡すようなものですが、元の方法は、マスマーケティング会社に自分で登録して、メールのコピーを送信するように依頼できるようにするようなものです。
IMO、元のコードは(多かれ少なかれ)正しいです。特に、正しいsender
を提供できます(これは、B
のイベントにサブスクライブしていると思う人にとってはB
インスタンスである必要があります)。
イベントがサブスクライブされていない場合に実行時のオーバーヘッドを減らすためのいくつかのトリックがありますが、これはmoreコードを追加します:
class B {
A m_A = new A();
private EventType eventB;
public event EventType EventB {
add { // only subscribe when we have a subscriber ourselves
bool first = eventB == null;
eventB += value;
if(first && eventB != null) m_A.EventA += OnEventB;
}
remove { // unsubscribe if we have no more subscribers
eventB -= value;
if(eventB == null) m_A.EventA -= OnEventB;
}
}
protected void OnEventB(object sender, EventArgsType args) {
eventB?.Invoke(this, args); // note "this", not "sender"
}
}