Я думаю Реактивные расширения для .NET - это точно то, что вы ищете.
Идея * такова:
Сначала определите класс, производный от EventArgs
и включающий в себя информацию, которую вы хотите (в частности, любой «индекс», который вы имели в виду). Примерно так:
public class IndexedEventArgs : EventArgs {
public string Index { get; private set; }
public IndexedEventArgs(string index) {
Index = index;
}
// ...
}
Далее, для класса, который будет вызывать события, реализуйте одно событие, используя EventHandler<TEventArgs>
и этот класс, который вы только что определили. В этом определении класса создайте объект, который реализует IObservable
следующим образом:
public class ClassWithIndexedEvents {
public event EventHandler<IndexedEventArgs> IndexedEvent;
public IObservable Events { get; private set; }
public ClassWithIndexedEvents() {
// yeah, this feels a little weird, but it works
Events = Observable.FromEvent<IndexedEventArgs>(this, "IndexedEvent");
}
// ...
}
Теперь, в вашем коде, где вы хотите подписаться только на события, соответствующие определенному индексу, вы можете фильтровать ваше свойство Events
точно так же, как и IEnumerable
:
// code mangled to fit without scrolling
public IDisposable CreateSubscription(
string eventIndex,
Action<IEvent<IndexedEventArgs>> handler) {
return Events.Where(e => e.Index == eventIndex).Subscribe(handler);
}
Обратите внимание, что метод Subscribe
возвращает объект IDisposable
; это ваш ключ к последующей отмене подписки отфильтрованного события, на которое вы только что подписались. Код довольно очевиден:
var fooSubscription = objectWithIndexedEvents.CreateSubscription(
"foo",
e => DoSomething(e)
);
// elsewhere in your code
fooSubscription.Dispose();
* Отказ от ответственности: я пишу весь этот код более или менее из памяти того, как работает Rx; Я не проверял это, так как у меня не установлено Rx на машине, которую я сейчас использую. Я могу проверить завтра на другом компьютере, чтобы убедиться, что все написано правильно; на данный момент это должно как минимум служить иллюстрацией, чтобы дать вам представление о том, как работает Rx. Чтобы узнать больше, вы всегда можете посмотреть учебники Rx онлайн.