シナリオは次のとおりです。
私は多くの異なるイベントを購読するクラスを持っています:
ProviderOfFruit.Event += OnFruitHarvested;
ProviderOfCars.Event += OnCarBrokeDown;
ProviderOfPeople.Event += OnPersonAwoke;
...etc
後で、これらすべてから同時に退会したいと思います。私はこれを完全に書き出す運命にありますか?
ProviderOfFruit.Event -= OnFruitHarvested;
ProviderOfCars.Event -= OnCarBrokeDown;
ProviderOfPeople.Event -= OnPersonAwoke;
...etc
または、次の方針に沿って何かを行う方法はありますか?
ListOfEvents.Unsubscibe(); ?
注:すべてのサブスクライバーのイベントをクリアしたくありません。多くのクラスがイベントにサブスクライブされています。それらのクラスの1つに、サブスクライブしているイベントのサブスクライブを解除してもらいたいだけです。ここでの目的は、特定のイベントから退会することを決して忘れないことです。
次のパターンを使用できます。最初に、構築時に渡す任意の関数を実行し、破棄時に別の関数を実行するクラスを作成します。
public class EventSubscription : IDisposable {
private readonly Action _unsubscribe;
private EventSubscription(Action subscribe, Action unsubscribe) {
_unsubscribe = unsubscribe;
subscribe();
}
public static IDisposable Create(Action subscribe, Action unsubscribe) {
return new EventSubscription(subscribe, unsubscribe);
}
public void Dispose() {
_unsubscribe();
}
}
次に、イベントをサブスクライブするクラスにフィールドを作成します。
private static readonly List<IDisposable> _subscriptions = new List<IDisposable>();
そして、このようにサブスクライブします:
_subscriptions.Add(EventSubscription.Create(
() => Event1 += OnEvent1,
() => Event1 -= OnEvent1));
_subscriptions.Add(EventSubscription.Create(
() => Event2 += OnEvent2,
() => Event2 -= OnEvent2));
登録を解除する必要がある場合は、次のようにしてください。
_subscriptions.ForEach(c => c.Dispose());
利点には、一度にすべてのサブスクリプションを解除することと、同じ呼び出しで常にペアでパス+=
と-=
ハンドラーを渡すため、サブスクリプションを解除することを忘れる可能性がはるかに少ないことが含まれます。
これのバリエーションは、この汎用クラスです。
public class Disposable : IDisposable {
private readonly Action _action;
private Disposable(Action action) {
_action = action;
}
public static IDisposable FromAction(Action action) {
return new Disposable(action);
}
public void Dispose() {
_action();
}
}
すでに多くの場所(.NETリアクティブ拡張など)で見つけることができますが、そうでない場合は、自分で実装できます。次に、上記のコードは次のようになります。
Event1 += OnEvent1;
_subscriptions.Add(Disposable.FromAction(() => Event1 -= OnEvent1));
もちろん、IDisposableを使用する必要はありません。アクションのリストを作成するだけで済みます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加