C#订阅事件时,使用发布者的泛型集合

时间:2015-07-02 20:03:58

标签: c#

订阅活动的最佳方式是什么,订阅者使用的是事件发布类的通用集合?

简要概述一下,设置是这样的:

public class PublisherClass
{
    public event EventHandler<CustomEventArgs> DoneSomethingEvent;
...


public class SubscriberClass
{
    public List<PublisherClass> publisherClassList { get; set; }
...

现在,如果我只是使用PublisherClass,那就简单了:

publisherClass.DoneSomethingEvent += MyEventHandler;

如果我正在使用此类的通用集合,我该怎么做?

1 个答案:

答案 0 :(得分:0)

您需要对泛型类型设置约束,并且该约束需要是定义您要订阅的事件的类或接口。

public interface IDoSomthingPublisher
{
    event EventHandler<CustomEventArgs> DoneSomethingEvent;
}

public class PublisherClass : IDoSomthingPublisher
{
    public event EventHandler<CustomEventArgs> DoneSomethingEvent;
...
}


public class SubscriberClass<T> where T : IDoSomthingPublisher
{
    private List<T> _publisherClassList;

    public List<T> PublisherClassList 
    {
        get
        {
            return _publisherClassList;
        }
        set
        {
            if(_publisherClassList != null)
            {
                foreach(T item in _publisherClassList)
                {
                    //unsubscribe old events
                    item -= MyEventHandler;
                }
            }

            _publisherClassList = value;

            if(_publisherClassList != null)
            {
                foreach(T item in _publisherClassList)
                {
                    //subscribe to new events
                    item += MyEventHandler;
                }
            }
        }
    }
}

您可能希望将List<T>换成ObserveableCollection<T>,这样您就可以在课程表外添加或删除项目时收到通知。

public class SubscriberClass<T> where T : IDoSomthingPublisher
{
    private ObserveableCollection<T> _publisherClassList;

    public ObserveableCollection<T> PublisherClassList 
    {
        get
        {
            return _publisherClassList;
        }
        set
        {
            if(_publisherClassList != null)
            {
                _publisherClassList -= CollectionChangedHandler;
                foreach(T item in _publisherClassList)
                {
                    //unsubscribe old events
                    item -= MyEventHandler;
                }
            }

            _publisherClassList = value;

            if(_publisherClassList != null)
            {
                _publisherClassList += CollectionChangedHandler;
                foreach(T item in _publisherClassList)
                {
                    //subscribe to new events
                    item += MyEventHandler;
                }
            }
        }
    }


    private void CollectionChangedHandler(object sender, NotifyCollectionChangedEventArgs args)
    {
        if(args.Action == NotifyCollectionChangedAction.Move)
            return; //Don't need to change subscriptions for moves.

        if(args.Action == NotifyCollectionChangedAction.Reset)
            throw new NotImplementedException("I leave this to you to solve");

        foreach(var item in args.OldItems)
        {
             item -= MyEventHandler;
        }
        foreach(var item in args.NewItems)
        {
             item += MyEventHandler;
        }
    }
}