CA1063: IDisposable을 올바르게 구현하십시오.
속성 | 값 |
---|---|
규칙 ID | CA1063 |
제목 | IDisposable을 올바르게 구현하십시오. |
범주 | 디자인 |
수정 사항이 주요 변경인지 여부 | 주요 변경 아님 |
.NET 9에서 기본적으로 사용 | 아니요 |
원인
System.IDisposable 인터페이스가 제대로 구현되지 않았습니다. 문제의 가능한 원인은 다음과 같습니다.
- IDisposable는 클래스에서 다시 구현됩니다.
-
Finalize
가 다시 재정의됩니다. -
Dispose()
가 재정의됩니다. -
Dispose()
메서드가 public이나 sealed나 이름이 Dispose가 아닙니다. -
Dispose(bool)
는 protected거나, virtual이거나, unsealed가 아닙니다. - Unsealed 형식의 경우
Dispose()
는Dispose(true)
를 호출해야 합니다. - Unsealed 형식의 경우
Finalize
구현은Dispose(bool)
또는 기본 클래스 종료자 중 하나 또는 둘 다를 호출하지 않습니다.
해당 패턴 중 하나를 위반하면 경고 CA1063이 트리거됩니다.
IDisposable 인터페이스를 선언하고 구현하는 모든 unsealed 형식은 자체 protected virtual void Dispose(bool)
메서드를 제공해야 합니다.
Dispose()
는 Dispose(true)
를 호출해야 하고 종료자는 Dispose(false)
를 호출해야 합니다.
IDisposable 인터페이스를 선언하고 구현하는 unsealed 형식을 만드는 경우 Dispose(bool)
를 정의하고 호출해야 합니다. 자세한 내용은 관리되지 않는 리소스 정리(.NET 가이드) 및 Dispose 메서드 구현을 참조하세요.
기본적으로 이 규칙은 외부에 표시되는 형식만 확인하지만 이는 구성 가능합니다.
규칙 설명
모든 IDisposable 형식은 Dispose 패턴을 올바르게 구현해야 합니다.
위반 문제를 해결하는 방법
코드를 검사하고 다음 해결 방법을 확인하여 해당 위반을 해결합니다.
형식에 의해 구현된 인터페이스 목록에서 IDisposable을 제거하고 대신 기본 클래스 Dispose 구현을 재정의합니다.
형식에서 종료자를 제거하고 Dispose(bool disposing)를 재정의한 후 ‘disposing’이 false인 코드 경로에 종료 논리를 넣습니다.
Dispose(bool disposing)를 재정의한 후 ‘disposing’이 true인 코드 경로에 삭제 논리를 추가합니다.
Dispose()가 public 및 sealed로 선언되었는지 확인합니다.
Dispose 메서드의 이름을 Dispose로 바꾸고 public 및 sealed로 선언되어 있는지 확인합니다.
Dispose(bool)가 protected, virtual, unsealed로 선언되었는지 확인합니다.
Dispose(true)를 호출하고 현재 개체 인스턴스(SuppressFinalize 또는 Visual Basic에서
this
)에서Me
를 호출한 후 반환되도록 Dispose()를 수정합니다.Dispose(false)를 호출한 후 반환되도록 종료자를 수정합니다.
IDisposable 인터페이스를 선언하고 구현하는 봉인되지 않은 형식을 만드는 경우 IDisposable 구현이 섹션 앞부분에서 설명한 패턴을 따르는지 확인합니다.
경고를 표시하지 않는 경우
이 규칙에서는 경고를 표시해야 합니다.
참고
다음이 모두 적용되는 경우 이 규칙에서 가양성 경고가 표시될 수 있습니다.
- Visual Studio 2022 버전 17.5 이상을 이전 버전의 .NET SDK(.NET 6 이하)와 함께 사용하고 있습니다.
- .NET 6 SDK 분석기 또는 이전 버전의 분석기 패키지(예: Microsoft.CodeAnalysis.FxCopAnalyzers)를 사용하고 있습니다.
-
IDispose
구현에 특성이 있습니다.
이 경우 가양성 경고가 표시되지 않도록 하는 것이 안전합니다. 가양성은 C# 컴파일러의 호환성이 손상되는 변경으로 인해 발생합니다. 가양성 경고에 대한 수정 사항이 포함된 최신 분석기를 사용하는 것이 좋습니다. Microsoft.CodeAnalysis.NetAnalyzers 버전 7.0.0-preview1.22464.1 이상으로 업그레이드하거나 .NET 7 SDK에서 분석기를 사용하세요.
분석할 코드 구성
다음 옵션을 사용하여 이 규칙이 실행될 코드베이스 부분을 구성합니다.
이 규칙, 적용되는 모든 규칙 또는 적용되는 이 범주(디자인)의 모든 규칙에 대해 이 옵션을 구성할 수 있습니다. 자세한 내용은 코드 품질 규칙 구성 옵션을 참조하세요.
특정 API 화면 포함
api_surface 옵션을 설정하여 접근성에 따라 이 규칙을 실행할 코드베이스의 일부를 구성할 수 있습니다. 예를 들어 규칙이 퍼블릭이 아닌 API 표면에서만 실행되도록 지정하려면 프로젝트의 .editorconfig 파일에 다음 키-값 쌍을 추가합니다.
dotnet_code_quality.CAXXXX.api_surface = private, internal
참고
XXXX
CAXXXX
부분을 해당 규칙의 ID로 바꿉니다.
의사 코드 예제
다음 의사 코드는 관리형 리소스와 네이티브 리소스를 사용하는 클래스에서 Dispose(bool)
을 구현하는 방법에 대한 일반적인 예를 제공합니다.
public class Resource : IDisposable
{
private bool isDisposed;
private IntPtr nativeResource = Marshal.AllocHGlobal(100);
private AnotherResource managedResource = new AnotherResource();
// Dispose() calls Dispose(true)
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
protected virtual void Dispose(bool disposing)
{
if (isDisposed) return;
if (disposing)
{
// free managed resources
managedResource.Dispose();
}
// free native resources if there are any.
if (nativeResource != IntPtr.Zero)
{
Marshal.FreeHGlobal(nativeResource);
nativeResource = IntPtr.Zero;
}
isDisposed = true;
}
// NOTE: Leave out the finalizer altogether if this class doesn't
// own unmanaged resources, but leave the other methods
// exactly as they are.
~Resource()
{
// Finalizer calls Dispose(false)
Dispose(false);
}
}
참고 항목
.NET