Вы хотите удалить обработчики, если содержащий объект находится в подвешенном состоянии после удаления всех ссылок на него в вашем приложении.
Например ...
public class LostInLimbo
{
private Villain _problem;
public void SetVillain(Villain problem)
{
problem.SomeEvent += this.SomeHandler;
_problem = problem;
}
}
Учитывая этот класс, если мы сделаем следующее:
Villain foo = new Villain();
LostInLimbo victim = new LostInLimbo();
victim.SetVillain(foo);
victim = null;
экземпляр victim
теперь "просочился".На него ссылается foo
и, следовательно, он не будет собран;однако вы не можете получить доступ к этому экземпляру.Сделайте это несколько сотен тысяч раз, и у вас может возникнуть проблема.
В этом случае вы бы хотели, чтобы LostInLimbo реализовал IDisposable, где вы можете отцепить событие:
var temp = _problem;
_problem = null;
if (temp != null_
temp -= this.SomeHandler;
Аналогично,Вы можете получить утечку, если сделаете это:
public class LostInLimbo
{
public Villain Problem {get;private set;}
public LostInLimbo()
{
Problem = new Villain();
Problem.SomeEvent += this.SomeHandler;
}
}
и выполните следующую
var temp = new LostInLimbo().Villain;
Та же ситуация.Злодей держит ссылку на экземпляр LostInLimbo, но у вас нет доступа к этому экземпляру.Опять же, реализация IDisposable позволит экземпляру LostInLimbo отсоединиться.Конечно, есть и другие проблемы с этим, но это всего лишь пример.
Если, однако, у вас есть такая ситуация:
public class LostInLimbo
{
private Villain _problem;
public LostInLimbo()
{
_problem = new Villain();
_problem.SomeEvent += this.SomeHandler;
}
}
Нет проблем.Только LostInLimbo содержит ссылку на _problem, а _problem не содержит ссылок ни на один экземпляр LostInLimbo, кроме того, который «владеет» им.После того, как этот экземпляр собран, так же и _problem.
В ответ на ваше обновление я сделаю следующее.
Сначала, когда элемент добавляется в коллекцию, коллекция подключается к элементу (переопределяет любой метод, добавляющий элемент в коллекцию).Когда элемент удаляется из коллекции, коллекция отсоединяется от элемента (опять же, переопределите любой метод, который удаляет элемент из коллекции).Я бы также реализовал IDisposable для очистки коллекции при утилизации.Я хотел бы убедиться, что любой тип, который использовал коллекцию, также реализует IDisposable.