Dois-je mettre en œuvre GC.SupressFinalize sur IDisposable ET Finaliser?
-
25-09-2019 - |
Question
La liste de vérification de code dans mon nouveau client a les suivantes -
Classe mise en œuvre Dispose et Finaliser devrait avoir un appel à la mise en œuvre GC.SupressFinalize Éliminez
Pourquoi?
Faut-il pas lu comme classe implémentant l'interface IDisposable devrait avoir un appel à GC.SupressFinalize dans la mise en œuvre Jeter?
Ou Suis-je manque quelque chose de stupide?
La solution
Vous êtes absent le fait que les besoins ne sont pas tous à usage unique classe finaliseur - en fait, très peu le font, notamment en fonction du type de SafeHandle
de .NET 2.0. S'il n'y a pas finaliseur, pourquoi auriez-vous besoin d'appeler SuppressFinalize
?
Autres conseils
Il est précis. Si la méthode a fait son travail alors il n'y a plus de point de Dispose (bool) pour laisser le finaliseur faire à nouveau. Calling GC.SuppressFinalize () est une optimisation, vous arrêtez .NET de prendre la peine d'appeler un finaliseur qui ne fait rien.
J'ai remarqué que vous avez écrit classe avec un grand C. C'est une indication que vous écrivez votre code en VB.NET. Attention, l'IDE fait la chose mauvais dans 99,99% des cas. Dès que vous appuyez sur Entrée après avoir tapé "implémente IDisposable", il insère le mauvais code:
Private disposedValue As Boolean = False ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free other state (managed objects).
End If
' TODO: free your own state (unmanaged objects).
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
#Region " IDisposable Support "
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
Beurk. C'est la mise en œuvre d'un boilerplate finaliseur, bien documenté dans la bibliothèque MSDN btw. C'est faux. Il est extrêmement rare d'avoir besoin en fait un finaliseur, les classes .NET prennent déjà en charge eux-mêmes. Si vous faites vraiment utiliser une poignée de système d'exploitation, vous devez utiliser l'une des classes dérivées SafeHandle. Ou écrire votre propre emballage.
Modifier revenir à ceci:
Public Sub Dispose() Implements IDisposable.Dispose
someField.Dispose()
'' maybe some more
''...
End Sub