Как отменить регистрацию "анонимного" обработчика событий

Скажите, если я слушаю событие:

Subject.NewEvent += delegate(object sender, NewEventArgs e)
{
    //some code
}); 

Теперь, как я могу зарегистрировать это событие? Или просто пропустить утечку памяти?

Ответ 1

Если вам нужно отменить регистрацию события, я рекомендую избегать анонимных делегатов для обработчика событий.

Это один случай, когда присвоение этого локальному методу лучше - вы можете отписаться от события чисто.

Ответ 2

Дайте вашему экземпляру анонимного делегата имя:

EventHandler<NewEventArg> handler = delegate(object sender, NewEventArgs e)
{
    //some code
};

Subject.NewEvent += handler;
Subject.NewEvent -= handler;

Ответ 3

Чтобы удалить обработчик при первом вызове:

//SubjectType Subject = ..... already defined if using (2)

EventHandler handler = null;
handler = delegate(object sender, EventArgs e)
{
    // (1)
    (sender as SubjectType).NewEvent -= handler;
    // or
    // (2) Subject.NewEvent -= handler;

    // do stuff here
};

Subject.NewEvent += handler;

Ответ 4

Вы можете создать метод для отмены регистрации всех слушателей события. Это не совсем то, что вы хотите, но иногда это может быть полезно. Например (это действительно работает =)):

    class Program {
    static void Main(string[] args) {
        A someClass = new A();
        someClass.SomeEvent += delegate(object sender, EventArgs e) {
            throw new NotImplementedException();
        };

        someClass.ClearEventHandlers();
        someClass.FireEvent();

        Console.WriteLine("No error.");
    }

    public class A {
        public event EventHandler SomeEvent;

        public void ClearEventHandlers() {
            Delegate[] delegates = SomeEvent.GetInvocationList();
            foreach (Delegate delegate in delegates) {
                SomeEvent -= (EventHandler) delegate;
            }
        }

        public void FireEvent() {
            if (SomeEvent != null) {
                SomeEvent(null, null);
            }
        }
    }
}

Ответ 5

Вам нужно имя для вашей анонимной функции, и тогда вы можете делать это только до тех пор, пока имя находится в области видимости:

    var handler = new EventHandler(delegate(object o, EventArgs e)
    {
        //do something...
    };

    Subject.NewEvent += handler;

    // later on while handler is still in scope...

    Subject.NewEvent -= handler;

Ответ 6

Вам нужно отменить регистрацию по какой-либо причине, кроме утечки?

Что касается бит "Или просто разрешить утечку памяти", когда объект очищается сборщиком мусора, ваш анонимный делегат также должен быть очищен, поэтому утечки не должно быть.