Управление подписками на события
Итак, небольшая заметка на тему того, как я работаю с подписками на события. Проблема такая: у меня есть XMPP-клиент, он генерирует тучу событий, которые хочется отловить, но помимо этого, еще иногда нужно делать reset этому клиенту, напрочь удаляя все подписки и создавая новые.
Для начала, я создаю класс DisposableCollection который умеет вызывать Dispose() на каждом элементе коллекции:
public sealed class DisposableCollection : Collection<IDisposable>, IDisposable
{
public void Dispose()
{
foreach (var obj in this)
obj.SafeDispose();
}
}
SafeDispose() в коде выше – это всего лишь Dispose() с проверкой на null. Метод также возвращает «флаг успешности», что порой бывает полезно.
public static bool SafeDispose(this IDisposable thіs)
{
if (thіs != null)
{
thіs.Dispose();
return true;
}
return false;
}
Еще один extension method — это инверсия потока управления для добавления элементов в коллекцию:
public static T AddTo<T>(this T thіs, Collection<T> coll)
{
coll.Add(thіs);
return thіs;
}
А теперь всем этим можно пользоваться. Для подписок используем ReactiveExtensions.
public sealed class XmppConnectionManager : IResetable
{
private XmppClient client;
private DisposableCollection subscriptions;
private void InitializeEvents()
{
// wire up events
Observable.FromEventPattern<ExceptionEventArgs>(x => client.OnError += x, x => client.OnError -= x)
.Subscribe(x => OnError(x.EventArgs))
.AddTo(subscriptions);
Observable.FromEventPattern<EventArgs>(x => client.OnLogin += x, x => client.OnLogin -= x)
.Subscribe(x => OnLogin(x.EventArgs))
.AddTo(subscriptions);
...
}
}
Соответственно, если нужно вдруг отписаться от всех подписок, это делается очень быстро:
subscriptions.SafeDispose();
А теперь загадка: почему методы расширения, приведенные выше, компилируются несмотря на название параметра thіs? Дам намек: как ключевое слово имя параметра не подсветилось.

Статический метод?
Юрий
2 Август 2011 в 9:23
Не очень понял вопрос…
Dmitri
2 Август 2011 в 20:05
Кирилическая «і» в названии параметра – это жесть. Надо было до такого додуматься :о)
Игорь
2 Август 2011 в 10:52
Зная о любви к необычным символам, можно предположить, что в имени параметра используется какой-нибудь символ не из латинского алфавита.
sombre hombre
2 Август 2011 в 10:54
Именно так! Используется украинская буква i.
Dmitri
2 Август 2011 в 20:05
Я взял себе за правило всегда в extention методах именовать входной this параметр как “self”.
public static bool SafeDispose(this IDisposable self)
{
…
}
ilya
2 Август 2011 в 11:44
да, это лучше чем this с украинской i =)
навеяно питоном?)
Jamon Portu
4 Август 2011 в 15:01
Вот за такой this лично я бы руки отрывал.
А в остальном ничего метод, удобно.
Nevermind
4 Август 2011 в 21:22