Vous souhaitez supprimer les gestionnaires si l'objet conteneur est conservé dans les limbes après que toutes les références dans votre application ont été supprimées.
Par exemple ...
public class LostInLimbo
{
private Villain _problem;
public void SetVillain(Villain problem)
{
problem.SomeEvent += this.SomeHandler;
_problem = problem;
}
}
Compte tenu de cette classe, si nous faisons ce qui suit:
Villain foo = new Villain();
LostInLimbo victim = new LostInLimbo();
victim.SetVillain(foo);
victim = null;
l'instance victim
est maintenant "fuite". Il est référencé par foo
et ne sera donc pas collecté; cependant, vous ne pouvez pas accéder à cette instance. Faites-le quelques centaines de milliers de fois et vous pourriez avoir un problème.
Dans ce cas, vous voulez LostInLimbo à mettre en œuvre IDisposable, où vous pouvez décrochez l'événement:
var temp = _problem;
_problem = null;
if (temp != null_
temp -= this.SomeHandler;
De même, vous pourriez vous retrouver avec une fuite si vous faites ceci:
public class LostInLimbo
{
public Villain Problem {get;private set;}
public LostInLimbo()
{
Problem = new Villain();
Problem.SomeEvent += this.SomeHandler;
}
}
et effectuer les opérations suivantes
var temp = new LostInLimbo().Villain;
Même situation. Villain contient une référence à l'instance de LostInLimbo, mais vous n'avez pas accès à cette instance. Encore une fois, l'implémentation de IDisposable permettra à l'instance de LostInLimbo de se décrocher elle-même. Bien sûr, il y a d'autres problèmes avec cela, mais ce n'est qu'un exemple. Cependant, vous avez
Si cette situation:
public class LostInLimbo
{
private Villain _problem;
public LostInLimbo()
{
_problem = new Villain();
_problem.SomeEvent += this.SomeHandler;
}
}
il n'y a pas de soucis. Seul LostInLimbo contient une référence à _problem, et _problem ne contient aucune référence à une instance de LostInLimbo à l'exception de celle qui la "possède". Une fois cette instance collectée, il en est de même de _problem.
En réponse à votre mise à jour, je voudrais procéder comme suit. Tout d'abord, lorsqu'un élément est ajouté à la collection, la collection se connecte à l'élément (remplace toute méthode qui ajoute un élément à la collection). Lorsqu'un élément est supprimé de la collection, la collection se déconnecte de l'élément (à nouveau, remplacez toute méthode qui supprime un élément de la collection). Je voudrais également implémenter IDisposable pour vider la collection sur disposer. Je m'assurerais que tout type qui utilise la collection implémente IDisposable.
Comme vous l'avez expliqué, c'est exactement ce que je fais en ce moment, cependant, à la lecture de votre réponse, il ne semble pas que je doive vider la collection quand j'en ai fini, tant que j'ai défini la référence à la collection à null. Est-ce juste pour l'exhaustivité? – Jules
@Jules Je le fais habituellement, pour être complet. Si je me débarrasse d'une collection, j'obtiendrai tous les articles de la collection, j'éclaircirai la collection, puis je forgerai ce que j'ai et je m'en débarrasserai. Juste mon habitude particulière, et il est plus facile d'avoir une méthode Dispose que vous pouvez appeler plus d'une fois sans lancer une exception. – Will