Question

Existe-t-il une méthode ou une méthode légère pour vérifier si une référence concerne un objet supprimé?

P.S. - Ceci est juste une curiosité (dors bien, pas dans le code de production). Oui, je sais que je peux intercepter ObjectDisposedException lorsque j'essaie d'accéder à un membre de l'objet.

Était-ce utile?

La solution

Cela dépend, il existe des objets IDisposable qui permettent d’appeler autant que vous le souhaitez la méthode Dispose , et il existe des objets IDisposable qui lancez ObjectDisposedException . Dans ce cas, ces objets doivent suivre l'état (généralement implémenté avec un champ booléen privé isDisposed ).

Autres conseils

Non - l'implémentation par défaut du modèle IDisposable ne le prend pas en charge

System.Windows.Forms.Control a un IsDisposed propriété qui est défini sur true après que Dispose () a été appelé . Dans vos propres objets IDisposable, vous pouvez facilement créer une propriété similaire.

Il n’existe rien 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 une propriété IsDisposed (ou quelque chose de similaire, le nom n'est qu'une convention), vous n'avez aucun moyen de le savoir.

Mais s'il s'agit de votre classe et que vous suivez la implémentation canonique IDisposable , puis exposez simplement le champ _disposed ou _isDisposed en tant que propriété et vérifiez-le.

La méthode Dispose est requise pour effectuer le nettoyage nécessaire avant l'abandon d'un objet. si aucun nettoyage n'est requis, il n'est pas nécessaire de faire quoi que ce soit. Demander à un objet de savoir s'il a été supprimé, même lorsque la méthode Dispose ne ferait normalement rien, nécessiterait de nombreux objets IDisposable pour ajouter un indicateur pour un avantage très limité. .

Il aurait peut-être été utile que IDisposable inclue deux propriétés, l'une indiquant si un objet doit être éliminé et l'une d'entre elles indiquant que l'objet n'a pas été <. em> rendu inutile par élimination. Pour les objets où disposition fait quelque chose, les deux valeurs sont initialement vraies et deviennent fausses après Dispose . Pour les objets pour lesquels l'élimination ne nécessite aucun nettoyage, la première méthode peut toujours renvoyer false et la seconde toujours true, sans avoir à stocker d'indicateur. Je ne pense pas qu'il soit possible d'ajouter ces éléments à .NET maintenant.

Je vois que c'est vieux, mais je n'ai pas vu de réponse. Certains objets non jetables, comme un DataSet, ont un événement disposé que vous pouvez joindre.

class DisposeSample : IDisposable
{
    DataSet myDataSet = new DataSet();
    private bool _isDisposed;

    public DisposeSample()
    {
        // attach dispose event for myDataSet
        myDataSet.Disposed += MyDataSet_Disposed;
    }

    private void MyDataSet_Disposed(object sender, EventArgs e)
    {
        //Event triggers when myDataSet is disposed
        _isDisposed = true; // set private bool variable as true 
    }


    public void Dispose()
    {
        if (!_isDisposed) // only dispose if has not been disposed;
            myDataSet?.Dispose(); // only dispose if myDataSet is not null;
    }
}

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

If anObject IsNot Nothing Then anObject.Dispose()

Voici un exemple 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 objets principaux au sommet d'une routine, les utiliser dans une routine Try , puis les disposer dans un bloc Finally :

Private Sub Test()
    Dim aForm As System.Windows.Forms.Form = Nothing
    Try
        Dim sName As String = 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top