Disons que j'ai une classe avec un champ d'objet. Lorsque vous disposez () est appelé, je voudrais effacer la référence à cet objet. Le domaine privé ne peut être défini qu'une fois, si idéalement, j'aimerais qu'elle soit réadonnée, mais si elle est réadonnée, une erreur de compilation est une erreur de compilation lorsque j'essaie de relâcher la référence à l'objet pendant le dispositif (). Idéalement, j'aimerais avoir un bon éliminer et marquer le champ _value comme à la fois loadonly. Est-ce possible ou même nécessaire?
public class Foo : IDisposable { public Foo(object value) { _value = value; } public object Value { get { return _value; } } private readonly object _value; public void Dispose() { //Cleanup here _value = null // causes compile time error } }
4 Réponses :
Ce n'est pas nécessaire, même si c'était possible. P>
Dispose est généralement destiné à nettoyer les ressources non gérées, bien qu'il puisse y avoir des exceptions à cette règle (notez les commentaires). Cependant, dans cette situation, vous devriez permettre au collecteur des ordures de faire son travail. Il fonctionnera indéterminée une fois que les objets sont considérés comme n'ayant aucune racine active. Dans des circonstances normales, vous n'avez pas besoin de prendre des mesures pour le forcer. Écrivez simplement votre code avec des objets dans une portée correctement limitée et tout ira bien. P>
Il existe de nombreuses circonstances où l'élimination est appropriée et essentielle même pour des objets qui n'ont pas de composants non gérés. Tout objet qui reçoit des événements à partir d'un objet à effet plus long doit se désabonner tous ses événements (généralement effectués à partir de disposer) afin d'éviter d'être conservés en vie par l'objet à long terme.
qui n'est pas nécessaire ni correct. Voulant faire ce que vous demandez dans votre question semble indiquer que vous êtes quelque part accéder à un objet disposé, et c'est faux. P>
Plutôt que d'essayer de faire ce que vous avez demandé, vous devriez peut-être implémenter Comme d'autres l'ont noté, le modèle d'élimination est destiné à libérer des ressources non gérées. P> isdisposed code> (quel BTW fait partie du Standard Dispose modèle ) et vérifiez-le en premier. P>
Définition de la référence à NULL ne fait rien. Le collecteur des ordures va nettoyer l'objet lorsqu'il n'y a plus aucune référence à celle-ci, ce qui, dans ce cas, depuis que vous le faites dans la méthode d'élimination, probablement, l'instance de FOO est sur le point de ne plus avoir de références à elle et la différence de Le timing n'est probablement pas significatif. En règle générale, vous implémentez le modèle d'élimination car votre type dispose d'un membre une classe qui se met en évidence Idisposable (dans ce cas, le type est un objet, qui ne met pas à l'enclosibilité) ou que vous avez des ressources non gérées que vous souhaitez libérer de manière déterministe. Vous pouvez trouver une description du modèle Dispose ici . Notez que si vous créez une variable d'élément lisonly d'un type qui implémente Idisposable, vous pouvez appeler la méthode Dispose sur cet objet à l'intérieur de votre disposition de votre disposition:
public class SomeClass : IDisposable { private Boolean mDisposed; private readonly MemoryStream mStream = new MemoryStream(); // Could be any class that implements IDisposable public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected void Dispose(Boolean disposing) { if (disposing & !mDisposed) { mStream.Dispose(); // Could and should call Dispose mDisposed = true; } return; } }
Salut, gc.suppressfinisalise (ceci); a un effet? Comme je crois comprendre, GC ne conserve pas la référence de la soméclasse à la file d'attente de finalisation car il n'y a pas de finaliseur défini.
Suivez le lien pour le modèle d'élimination de ma réponse; Appeler GC.SuppressFinalize fait partie du motif. Dans ce cas, il peut ne pas avoir d'effet, mais c'est une bonne habitude d'entrer dans la mesure du fait que si le GC appelant la méthode de finale a des implications de performance.
C'est un article plus ancien, mais je fais face à la même question régulièrement parce que je me désabonnement d'objets que j'ai souscrits. p>
Je fais cette désupérité pendant le disposition, car ces objets vivent plus longtemps que cet objet, et la manière dont les délégués sont mis en œuvre signifie que l'éditeur garde l'abonné en vie, et non l'inverse comme nous le penserions. p>
Mais, lorsque vous vous désabonnez-vous des événements, vous avez la tendance naturelle à vouloir effacer également la référence à l'éditeur, ce qui n'est vraiment pas si grave. Je vous suggère de conserver la contrainte «Readonly», car cela rend les règles plus claires et le code plus robustes pendant que l'objet est toujours en vie. Si cela signifie que vous êtes assis avec la référence après le disposer, c'est bien parce que l'objet est maintenant
Dans cet exemple, vous abusez maladifs. Idisposable sont destinés à nettoyer la ressource natif du nettoyage déterministe.