Я искал в архивах и нашел много вопросов о том, что такое отправитель и почему вы должны использовать шаблон, но я ничего не видел о пользовательском событии и типе если отправитель.
Допустим, я создаю пользовательский класс с именем Subscription, и он реализует ISubscription, и у меня есть несколько аргументов события, называемых SubscriptionEventArgs. Если в подписке было событие с именем Изменено, что не так в сигнатуре события Изменено (отправитель ISubscription, SubscriptionEventArgs e)?
Небольшой код, помогающий задать вопрос:
public class SubscriptionEventArgs : EventArgs
{
// guts of event args go here
}
public interface ISubscription
{
event Action<ISubscription, SubscriptionEventArgs> Changed;
}
public class Subscription : ISubscription
{
public event Action<ISubscription, SubscriptionEventArgs> Changed;
private void OnChanged(SubscriptionEventArgs e)
{
if (Changed!= null)
{
Changed(this, e);
}
}
}
Если вы просто презираете использование действия вместо «EventHandler», то вы можете сделать то же самое, но с пользовательским универсальным «EventHandler».
public delegate void EventHandler<TSender, TEventArgs>(TSender sender, TEventArgs e);
public class SubscriptionEventArgs : EventArgs
{
// guts of event args go here
}
public interface ISubscription
{
event EventHandler<ISubscription, SubscriptionEventArgs> Changed;
}
public class Subscription : ISubscription
{
public event EventHandler<ISubscription, SubscriptionEventArgs> Changed;
private void OnChanged(SubscriptionEventArgs e)
{
if (Changed!= null)
{
Changed(this, e);
}
}
}
В ответ на запрос Ганса об образце обработчика событий:
public class SubscriptionCollection
{
// what is actually holding the subscriptions is not really relevant to the question
private List<ISubscription> _subscriptions;
public SubscriptionCollection()
{
_subscriptions = new List<ISubscription>();
}
public void Add(ISubscription subscription)
{
subscription.Changed += new EventHandler<ISubscription, SubscriptionEventArgs>(Subscription_Changed);
_subscriptions.Add(subscription);
}
private void Subscription_Changed(ISubscription sender, SubscriptionEventArgs e)
{
// Now when the subscription changed event is being handled by the collection
// I don't have to look up the subscription in the list by some key and I don't
// have to cast sender to the correct type because the event handler was typed
// correctly from the beginning.
}
}
Поиск подписки в списке может показаться тривиальным, но что, если я работаю с очень большими наборами данных и новые объемы данных поступают в приложение через поток в реальном времени. Затраты на то, чтобы остановиться и получить ссылку из списка или пройти этапы кастинга, не имеют смысла. Они дали нам дженерики в 2.0 для решения этой проблемы, поэтому я не понимаю, почему у нас тоже не было универсального обработчика событий, и это привело меня к вопросу, что не так с универсальным обработчиком событий?