CA1816: Wywołaj poprawnie GC.SuppressFinalize
TypeName |
CallGCSuppressFinalizeCorrectly |
CheckId |
CA1816 |
Kategoria |
Microsoft.Użycie |
Zmiana kluczowa |
Niekluczowa |
Przyczyna
Metoda, która jest implementacją IDisposable.Dispose nie wywołuje GC.SuppressFinalize.
Metoda, która nie jest implementacją IDisposable.Dispose wywołuje GC.SuppressFinalize.
Metoda wywołuje GC.SuppressFinalize i przekazuje coś innego niż this (Me w języku Visual Basic).
Opis reguły
Metoda IDisposable.Dispose pozwala użytkownikom zwolnić zasoby w dowolnym momencie, zanim obiekt stanie się dostępny dla mechanizmu wyrzucania elementów bezużytecznych.Jeśli metoda IDisposable.Dispose jest wywoływana, zwalnia zasoby obiektu.Z tego powodu finalizacja nie jest konieczna.Metoda IDisposable.Dispose powinna wywołać metodę GC.SuppressFinalize, aby mechanizm wyrzucania elementów bezużytecznych nie wywoływał finalizatora obiektu.
Aby zapobiec konieczności ponownej implementacji [System.IDisposable] typów dziedziczonych i aby ją wywołać, typy niezapieczętowane bez finalizatorów powinny nadal wywoływać GC.SuppressFinalize.
Jak naprawić naruszenia
Aby naprawić naruszenie tej reguły:
Jeśli metoda jest implementacją Dispose, dodaj wywołanie GC.SuppressFinalize.
Jeśli metoda nie jest implementacją Dispose, usuń wywołanie GC.SuppressFinalize lub przenieś je do implementacji typu Dispose.
Zmień wszystkie wywołania GC.SuppressFinalize, aby przekazywały this (Me w języku Visual Basic).
Kiedy pominąć ostrzeżenia
Pomiń ostrzeżenie i odstąp od tej reguły, tylko jeśli rozważasz użycie GC.SuppressFinalize do kontrolowania okresu istnienia innych obiektów.Nie pomijaj ostrzeżenia dotyczącego tej reguły, jeśli implementacja Dispose nie wywołuje GC.SuppressFinalize.W takiej sytuacji, jeśli finalizacja nie zostanie pominięta, obniżona zostanie wydajność i nie przyniesie żadnych korzyści.
Przykład
Poniższy przykład pokazuje metodę, która niepoprawnie wywołuje GC.SuppressFinalize.
Imports System
Imports System.Data.SqlClient
Namespace Samples
Public Class DatabaseConnector
Implements IDisposable
Private _Connection As New SqlConnection
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(True) ' Violates rules
End Sub
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If _Connection IsNot Nothing Then
_Connection.Dispose()
_Connection = Nothing
End If
End If
End Sub
End Class
End Namespace
using System;
using System.Data.SqlClient;
namespace Samples
{
public class DatabaseConnector : IDisposable
{
private SqlConnection _Connection = new SqlConnection();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(true); // Violates rule
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_Connection != null)
{
_Connection.Dispose();
_Connection = null;
}
}
}
}
}
Poniższy przykład pokazuje metodę, która poprawnie wywołuje GC.SuppressFinalize.
Imports System
Imports System.Data.SqlClient
Namespace Samples
Public Class DatabaseConnector
Implements IDisposable
Private _Connection As New SqlConnection
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If _Connection IsNot Nothing Then
_Connection.Dispose()
_Connection = Nothing
End If
End If
End Sub
End Class
End Namespace
using System;
using System.Data.SqlClient;
namespace Samples
{
public class DatabaseConnector : IDisposable
{
private SqlConnection _Connection = new SqlConnection();
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_Connection != null)
{
_Connection.Dispose();
_Connection = null;
}
}
}
}
}
Powiązane reguły
CA2215: Metody Dispose powinny wywoływać operację usuwania klasy podstawowej
CA2216: Typy usuwalne powinny deklarować finalizator