EventHandlers и анонимные делегаты/выражения лямбда

Я надеюсь прояснить некоторые вещи с анонимными делегатами и лямбда-выражениями, которые используются для создания метода обработчиков событий в С#; для меня как минимум.

Предположим, что у нас есть событие, которое добавляет анонимный делегат или выражение лямбда [для вас, счастливые толпы, которые могут использовать более новые версии .NET).

SomeClass.SomeEvent += delegate(object o, EventArg e) { //do something };

Я читал, что люди в прошлом забыли о событиях, которые по-прежнему имеют обработчики, которые мешают сбору мусора. Как можно было бы удалить добавленный обработчик, просто не установив SomeEvent в null в классе. Не будет ли это совсем новым обработчиком?

SomeClass.SomeEvent -= delegate(object o, EventArg e) { //do same thing };

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

SomeEventDelegate handler = new SomeEventDelegate(delegate(object o, EventArg e) { //do same thing });
SomeClass.SomeEvent += handler;
//... stuff
SomeClass.SomeEvent -= handler;

Опять же, я понимаю, что вы могли бы просто сделать...

public override Dispose(bool disposing)
{
    _someEvent = null;
    this.Dispose();
}

Но мне интереснее просто удалить динамически созданный метод из Event. Надеюсь, кто-то может пролить свет на это для меня. Спасибо!

Ответ 1

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

Обычно, когда что-то есть, оно все равно становится мусором, что означает, что у вас нет проблемы.

Проблема с событиями и GC - это если вы забыли удалить подписанный обработчик из другого объекта - то есть у вас есть слушатель, который находится, но никогда не будет собираться мусором, потому что все еще есть ссылка на него из события в другой объект.

Ответ 2

Я думаю, проблема в том, что вы, похоже, исходите из предположения, что наличие делегата, назначенного для события объекта, не позволяет GCed.

Это простое утверждение неверно.

Сказав, что воспринимаемая проблема исчезает.

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

Как бы такой процесс графического отображения удалось достичь этого объекта?

Ответ 3

Вы не можете.

Так же, как вы не можете создать анонимный тип вне своей области (за исключением некоторых трюков компилятора).

Вот почему он называется анонимным.

Вам нужно сохранить ссылку где-нибудь... или использовать отражение.