Share via


CA1816: GC.SuppressFinalize를 올바르게 호출하십시오.

속성
규칙 ID CA1816
타이틀 GC.SuppressFinalize를 올바르게 호출하세요.
범주 사용 현황
수정 사항이 주요 변경인지 여부 주요 변경 아님
.NET 8에서 기본적으로 사용 제안 사항

원인

이 규칙의 위반은 다음 항목에 의해 발생할 수 있습니다.

규칙 설명

IDisposable.Dispose 메서드를 사용하면 가비지 수집에 개체를 사용할 수 있게 되기 전에 언제든지 사용자가 리소스를 해제할 수 있습니다. IDisposable.Dispose 메서드가 호출되면 개체의 리소스를 해제합니다. 따라서 종료하지 않아도 됩니다. IDisposable.DisposeGC.SuppressFinalize를 호출하므로 가비지 수집기에서 개체의 종료자를 호출하지 않습니다.

종료자를 사용하는 파생 형식에서 IDisposable을 다시 구현하고 호출하지 않도록 하려면 종료자를 사용하지 않는 봉인되지 않은 형식에서 GC.SuppressFinalize를 호출해야 합니다.

위반 문제를 해결하는 방법

이 규칙의 위반 문제를 해결하려면

경고를 표시하지 않는 경우

다른 개체의 수명을 제어하기 위해 의도적으로 사용하는 GC.SuppressFinalize 경우에만 이 규칙의 경고를 표시하지 않습니다. Dispose의 구현이 GC.SuppressFinalize를 호출하지 않는 경우 이 규칙의 경고를 표시해야 합니다. 이 경우 종료를 표시하지 않는 데 실패하면 성능이 저하되고 장점이 없습니다.

경고 표시 안 함

단일 위반만 표시하지 않으려면 원본 파일에 전처리기 지시문을 추가하여 규칙을 사용하지 않도록 설정한 후 다시 사용하도록 설정합니다.

#pragma warning disable CA1816
// The code that's violating the rule is on this line.
#pragma warning restore CA1816

파일, 폴더 또는 프로젝트에 대한 규칙을 사용하지 않도록 설정하려면 구성 파일에서 심각도를 none으로 설정합니다.

[*.{cs,vb}]
dotnet_diagnostic.CA1816.severity = none

자세한 내용은 방법: 코드 분석 경고 표시 안 함을 참조하세요.

CA1816을 위반하는 예제

이 코드는 GC.SuppressFinalize를 호출하지만 this(C#) 또는 Me(Visual Basic)를 전달하지 않는 메서드를 보여 줍니다. 결과적으로 이 코드는 규칙 CA1816을 위반합니다.

Public Class DatabaseConnector
    Implements IDisposable

    Private _Connection As New SqlConnection

    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        ' Violates rules
        GC.SuppressFinalize(True)
    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
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;
            }
        }
    }
}

CA1816을 충족하는 예제

이 예제에서는 this(C#) 또는 Me(Visual Basic)를 전달하여 GC.SuppressFinalize를 올바르게 호출하는 메서드를 보여 줍니다.

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
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;
            }
        }
    }
}

참고 항목