Question

Dans Visual Studio, lorsque je tape la ligne " Implémente IDisposable ", l'EDI ajoute automatiquement:

  • une variable membre disposésValue
  • un Sub Dispose () implémente IDisposable.Dispose
  • un Sub Dispose (ByVal éliminant en tant que booléen)

Le Dispose () doit être laissé seul et le code de nettoyage doit être placé dans Dispose (disposer) .

Cependant, le Supprimer Finalize Pattern indique que vous devez également remplacer Sub Finalize () pour appeler Dispose (False) . Pourquoi l’IDE ??n’a-t-il pas ajouté cela? Dois-je l'ajouter moi-même, ou l'appelle-t-on implicitement?

EDIT: Pourquoi l'IDE ajoute-t-il automatiquement 80% des éléments requis, mais omet-il la méthode Finalize? L’intérêt de ce type de fonctionnalité de vous aider à ne pas ne pas oublier ces choses?

EDIT2: Merci à tous pour vos excellentes réponses, cela fait maintenant parfaitement sens!

Était-ce utile?

La solution

Si vous avez en réalité des ressources non gérées qui ne seront pas automatiquement nettoyées par le ramasse-miettes et nettoyées dans votre Dispose (), alors vous devriez en faire de même dans Finalize ().

Si vous implémentez IDisposable pour une autre raison, implémenter Finalize () n'est pas obligatoire.

La question de base est la suivante: si Dispose () n'était pas appelé et si vos déchets d'objet étaient collectés, une perte de mémoire serait-elle possible? Si oui, implémentez Finalize. Si non, vous n'en avez pas besoin. Évitez également de mettre en œuvre Finalize "simplement parce que c'est plus sûr". Les objets dotés de finaliseurs personnalisés peuvent potentiellement nécessiter deux passes GC pour les libérer - une fois pour les placer dans la file d'attente des finaliseurs en attente, et une seconde pour libérer réellement leur mémoire.

Autres conseils

Non, vous n'avez pas besoin de Finalize à moins de disposer de ressources non gérées pour le nettoyer.

Dans la plupart des cas, une classe est jetable car elle conserve des références à d'autres objets IDisposable gérés. Dans ce cas, aucune méthode de finalisation n'est nécessaire ou souhaitable.

Implements IDisposable

Public Overloads Sub Dispose() Implements IDisposable.Dispose

    Dispose(True)
    GC.SuppressFinalize(Me)

End Sub

Protected Overloads Sub Dispose(ByVal disposing As Boolean)

    If disposing Then
        ' Free other state (managed objects).
    End If
    ' Free your own state (unmanaged objects).
    ' Set large fields to null.
End Sub

Protected Overrides Sub Finalize()

    Dispose(False)
    MyBase.Finalize()

End Sub

Comme d'autres l'ont déjà dit, vous n'avez pas besoin de mettre en œuvre un finaliseur, à moins que vous ne disposiez directement de ressources non gérées. En outre, si vous travaillez avec .NET 2.0 ou une version ultérieure, il est peu probable que vous ayez besoin de mettre en œuvre un finaliseur, car SafeHandle permet généralement d’envelopper vos ressources non gérées.

J'ai écrit un blog assez long couvrant le fond et l'implémentation d'IDisposable et de finaliseurs il y a quelque temps, ce qui peut valoir la peine d'être lu si vous n'êtes pas tout à fait clair à ce sujet.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top