Проверка существующих «подключенных» методов - PullRequest
3 голосов
/ 29 февраля 2012

Возможно, я здесь неправильно понимаю что-то фундаментальное, поскольку я новичок в этих понятиях, поэтому, пожалуйста, потерпите меня.

В настоящее время я удаляю методы из события, например:

scheduleView.TouchDown -= scheduleView_TouchDown;

А потом в других случаях - добавление методов:

scheduleView.TouchDown += scheduleView_TouchDown;

Пока все работает нормально, и я могу понять, что можно добавить несколько методов, например:

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

Но как мне потом проверить, какие методы были подключены к этому событию?

Ответы [ 3 ]

8 голосов
/ 29 февраля 2012

Интересно, вы не можете (по крайней мере, снаружи). event только обязан предложить 2 средства доступа - add и remove. Существуют и другие методы доступа, определенные в спецификации CLI, но они не используются ни в C #, ни где-либо еще в AFAIK. Ключевой момент: мы не можем спросить event, что подписано (и действительно, нам не нужно знать). Все, что вы можете сделать, это: add или remove.

Если вы беспокоитесь о двойной подписке, обратите внимание, что если вы пытаетесь отписаться, а вы на самом деле не подписались, то при каждой вменяемой реализации это просто запрет; что означает, что вы можете сделать:

// 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);
    }
}

Основное использование для этого:

  • когда вы хотите выполнить обработку исключений для каждого подписчика
  • когда делегат возвращает значение или изменяет состояние, и вам нужно обрабатывать это для каждого подписчика
4 голосов
/ 29 февраля 2012

Да: если вы в классе, который публикует Событие, вы можете просто получить доступ к делегату и вызвать метод GetInvocationList, чтобы получить список подписчиков.

Нет: если вы работаете за пределами класса, так как делегат вам не доступен.Вы можете использовать рефлексию, но в лучшем случае это будет взлом.

1 голос
/ 29 февраля 2012

В типе, который объявляет событие, вы можете использовать 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!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...