检查现有的“有线”方法

时间:2012-02-29 13:22:26

标签: c# events methods delegates

我可能会误解一些基本的东西,因为我对这些概念不熟悉所以请耐心等待。

我正在从像这样的事件中删除方法:

scheduleView.TouchDown -= scheduleView_TouchDown;

然后在其他场合 - 添加方法:

scheduleView.TouchDown += scheduleView_TouchDown;

到目前为止一切正常,我可以理解可以添加几种方法,如下:

scheduleView.TouchDown += scheduleView_TouchDown;
scheduleView.TouchDown += scheduleView_AnotherTouchDownEventHandler;

但是我后来如何检查哪些方法连接到此事件?

3 个答案:

答案 0 :(得分:8)

有趣的是,你不能(至少从外面)。 event有义务提供2个访问者 - addremove。 CLI规范中定义了其他访问器方法,但它们不在C#或其他任何AFAIK中使用。关键点:我们不能问event订阅的内容(事实上,我们不应该知道)。您所能做的就是:addremove

如果您担心双重订阅,请注意,如果您尝试取消订阅并且您实际上没有订阅,那么在每个理智的实现中,这只是一个无操作;这意味着你可以这样做:

// make sure we are subscribed once but **only** once
scheduleView.TouchDown -= scheduleView_TouchDown;
scheduleView.TouchDown += scheduleView_TouchDown;

从提升event的代码的角度来看,您很少需要知道 - 只需:

// note I'm assuming a "field-like event" implementation here; otherwise,
// change this to refer to the backing-field, or the delegate from the
// event-handler-list
var handler = TouchDown;
if(handler != null) handler(this, EventArgs.Empty); // or similar

还有一种方法可以将委托列表分解为单个订阅者,但很少需要:

var handler = TouchDown;
if(handler != null) {
    foreach(EventHandler subscriber in handler.GetInvocationList()) {
        subscriber(this, EventArgs.Empty);
    }
}

主要用途是:

  • 当您希望基于每个订阅者执行异常处理时
  • 当委托返回值或更改状态,并且您需要基于每个订户处理

答案 1 :(得分:4)

是:如果您在发布事件的类中,您只需访问该委托,您就可以调用GetInvocationList方法获取订阅者列表。< / p>

否:如果你在外面这个班级,因为代表不会向你透露。你可以使用反射来实现它,但这最好是一个黑客。

答案 2 :(得分:1)

在声明事件的类型中,您可以使用GetInvocationList()找出订阅的代表:

public class EventProvider
{
    public event EventHandler SomeEvent;

    protected virtual void OnSomeEvent(EventArgs args)
    {
        if (SomeEvent != null)
        {
            var delegates = SomeEvent.GetInvocationList();
            foreach (var del in delegates)
            {
                Console.WriteLine("{0} has subscribed to SomeEvent", del.Method.Name);
            }
            SomeEvent(this, args);
        }
    }

    public void RaiseSomeEvent()
    {
        OnSomeEvent(EventArgs.Empty);
    }
}

public class Program
{
    public static void Main()
    {
        EventProvider provider = new EventProvider();
        provider.SomeEvent += Callback1;
        provider.SomeEvent += Callback2;
        provider.RaiseSomeEvent();
    }

    public static void Callback1(object sender, EventArgs e)
    {
        Console.WriteLine("Callback 1!");
    }

    public static void Callback2(object sender, EventArgs e)
    {
        Console.WriteLine("Callback 2!");
    }
}

这会产生以下输出:

Callback1 has subscribed to SomeEvent
Callback2 has subscribed to SomeEvent
Callback 1!
Callback 2!