Comment savoir si une référence d’object IDisposable est éliminée?

Existe-t-il une méthode, ou un autre moyen léger, pour vérifier si une référence est à un object éliminé?

PS – C’est juste une curiosité (bien dormir, pas en code de production). Oui, je sais que je peux intercepter l’ ObjectDisposedException en essayant d’accéder à un membre de l’object.

Cela dépend, il y a des objects IDisposable qui permettent d’appeler la méthode Dispose autant que vous voulez, et il y a des objects IDisposable qui lancent ObjectDisposedException . Dans un tel cas, ces objects doivent suivre l’état (généralement implémenté avec un champ booléen privé).

Non – L’implémentation par défaut du modèle IDisposable ne le prend pas en charge

System.Windows.Forms.Control a une propriété IsDisposed définie sur true après l’appel de Dispose() . Dans vos propres objects IDisposables, vous pouvez facilement créer une propriété similaire.

Il n’y a rien de construit qui permette cela. Vous devez exposer une propriété booléenne IsDisposed qui reflète un indicateur interne éliminé.

 public class SimpleCleanup : IDisposable { private bool disposed = false; public bool IsDisposed { get { return disposed; } } public SimpleCleanup() { this.handle = /*...*/; } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { // free only managed resources here } // free unmanaged resources here disposed = true; } } public void Dispose() { Dispose(true); } } 

Si ce n’est pas votre classe et qu’elle ne fournit pas de propriété IsDisposed (ou quelque chose de similaire – le nom n’est qu’une convention), alors vous n’avez aucun moyen de le savoir.

Mais si c’est votre classe et que vous suivez l’ implémentation canonique IDisposable , exposez simplement le champ _disposed ou _isDisposed en tant que propriété et vérifiez-le.

La méthode Dispose est requirejse pour effectuer le nettoyage requirejs avant qu’un object soit abandonné; si aucun nettoyage n’est requirejs, il n’est pas nécessaire de faire quoi que ce soit. Demander à un object de savoir s’il en a été disposé, même si la méthode Dispose ne ferait rien autrement, nécessiterait que de nombreux objects IDisposable ajoutent un indicateur pour des avantages très limités.

Cela aurait pu être utile si IDisposable incluait deux propriétés – une qui indiquait si un object devait être éliminé , et l’une d’entre elles indiquait que l’object n’avait pas été rendu inutile par l’élimination. Pour les objects où l’élimination fait réellement quelque chose, les deux valeurs seraient initialement vraies et deviendraient fausses après Dispose . Pour les objects où l’élimination n’a pas besoin de faire de nettoyage, la première méthode peut toujours renvoyer false et la seconde toujours, sans qu’il soit nécessaire de stocker un indicateur. Je ne pense pas qu’il soit possible d’append ces fonctionnalités à .NET maintenant.

Ce que j’aime faire, c’est déclarer les objects sans les initialiser, mais définir leurs valeurs par défaut sur Nothing . Ensuite, à la fin de la boucle, j’écris:

 If anObject IsNot Nothing Then anObject.Dispose() 

Voici un échantillon complet:

 Public Sub Example() Dim inputPdf As PdfReader = Nothing, inputDoc As Document = Nothing, outputWriter As PdfWriter = Nothing 'code goes here that may or may not end up using all three objects, ' such as when I see that there aren't enough pages in the pdf once I open ' the pdfreader and then abort by jumping to my cleanup routine using a goto .. GoodExit: If inputPdf IsNot Nothing Then inputPdf.Dispose() If inputDoc IsNot Nothing Then inputDoc.Dispose() If outputWriter IsNot Nothing Then outputWriter.Dispose() End Sub 

Cela fonctionne également très bien pour placer vos objects principaux en haut d’une routine, en les utilisant dans une routine Try , puis en les disposant dans un bloc Finally :

 Private Sub Test() Dim aForm As System.Windows.Forms.Form = Nothing Try Dim sName As Ssortingng = aForm.Name 'null ref should occur Catch ex As Exception 'got null exception, no doubt Finally 'proper disposal occurs, error or no error, initialized or not.. If aForm IsNot Nothing Then aForm.Dispose() End Try End Sub