2014-02-19 126 views
0

我不知道如何使用事件和委托从观察的类中获取观察者的集合。事件:从观察获得事件观察者

http://msdn.microsoft.com/en-us/library/aa645739%28v=vs.71%29.aspx

在这个例子中EventListener的一个实例被订阅ListWithChangedEvent的一个实例。使用香草观察者模式很容易获得正在监听ListWithChangedEvent的集合对象(因为它必须维护一系列观察者)。然而,使用事件,它稍微不清楚如何在观察者对象的ListWithChanged内产生这个集合。

它是这样的:

Changed.GetInvocationList().Select(item => item.Target).OfType<EventListener>().ToList(); 

似乎令人怀疑,似乎有点复杂。

编辑:这编译和给我我的答案。我只是有点担心,它是一个不好的方法来做到这一点。

+0

它编译了吗?它有用吗?你能打破它吗? – Gusdor

+0

您是否正在尝试在*负责该事件的对象内部执行此操作?你想用这个做什么?你想用静态方法发生什么?您还应该记住,执行订阅的代码可能不是包含处理事件的方法的代码... –

+0

@Gusdor是的。它编译了,对不起,我认为它不会。尽管如此,我仍然对此感到怀疑,我惊讶地发现它只是简单地获取侦听类实例的列表。 –

回答

1

你只是在那里,你只需要记住,你不能使用GetInvocationList()从代表外部的代理标记event,所以你需要声明一个支持字段或从在课堂上。

class EventListener 
{ 
    public EventPublisher publisher = new EventPublisher(); 

    public EventListener() 
    { 
     publisher.Event += HandleEvent; 
    } 

    void HandleEvent(object sender, EventArgs e) 
    { 
    } 
} 

class EventPublisher 
{ 
    public event EventHandler Event; 

    public List<EventListener> GetListeners() 
    { 
     return Event.GetInvocationList().Select(i => i.Target).OfType<EventListener>().ToList(); 
    } 
} 

编辑:如果你处理的第三方类,所以你不能在类中使用支持字段或致电GetInvocationList(),那么你可以使用反射:

var fieldInfo = typeof(EventPublisher).GetField("Event", BindingFlags.Instance | BindingFlags.NonPublic); 
var eventHandler = (EventHandler)fieldInfo.GetValue(listener.publisher); 
var listeners = eventHandler.GetInvocationList().Select(i => i.Target).ToList(); 
+0

谢谢。但是你知道你声明事件的显式方式与标准实现有什么不同吗? –

+0

请参阅我的回答中的编辑 – Dominic

+0

您*可以*在类中声明场类事件的委托本身。 (我刚刚仔细检查过。)另请注意,您的事件实现不是线程安全的,不像字段事件的实现。 –