CA2213: 삭제 가능한 필드는 삭제해야 합니다.
속성 | 값 |
---|---|
규칙 ID | CA2213 |
제목 | 삭제 가능한 필드는 삭제해야 합니다. |
범주 | 사용 현황 |
수정 사항이 주요 변경인지 여부 | 주요 변경 아님 |
.NET 9에서 기본적으로 사용 | 아니요 |
원인
System.IDisposable을 구현하는 형식은 IDisposable을 구현하는 형식의 필드를 선언합니다. 필드의 Dispose 메서드가 선언 형식의 Dispose 메서드에 의해 호출되지 않습니다.
규칙 설명
형식은 관리되지 않는 모든 리소스의 삭제를 담당합니다. 규칙 CA2213은 삭제 가능한 형식(즉, IDisposable을 구현하는 형식) T
가 삭제 가능한 형식 FT
의 인스턴스인 필드 F
를 선언하는지를 확인합니다. 포함하는 형식 T
의 메서드 또는 이니셜라이저 내에서 로컬로 만든 개체가 할당된 각 필드 F
에 대해 규칙은 FT.Dispose
호출을 찾으려고 시도합니다. 규칙은 T.Dispose
에 의해 호출되는 메서드와 한 수준 낮은(즉, T.Dispose
에 의해 호출되는 메서드에 의해 호출되는 메서드)를 검색합니다.
참고 항목
특수한 경우를 제외하면, 규칙 CA2213은 포함하는 형식의 메서드 및 이니셜라이저 내에서 로컬로 생성된 삭제 가능한 개체를 할당한 필드에 대해서만 발생합니다. 개체를 만들거나 T
형식 외부에서 할당한 경우에는 규칙이 발생하지 않습니다. 이렇게 하면 포함하는 형식이 개체의 삭제를 담당하지 않는 경우의 노이즈가 줄어듭니다.
특별 케이스
CA2213 규칙은 할당된 개체가 로컬로 생성되지 않은 경우에도 다음 형식의 필드에 대해 발생합니다.
이러한 형식 중 하나인 개체를 생성자에 전달한 후 필드에 할당하면 새로 생성된 형식으로 ‘삭제 소유권이 전송’됨을 나타냅니다. 즉, 새로 생성된 형식이 이제 개체의 삭제를 담당합니다. 개체가 삭제되지 않으면 CA2213이 위반됩니다.
위반 문제를 해결하는 방법
이 규칙 위반 문제를 해결하려면 IDisposable을 구현하는 형식의 필드에 대해 Dispose를 호출합니다.
경고를 표시하지 않는 경우
다음 경우에는 이 규칙의 경고를 표시하지 않아도 됩니다.
- 플래그가 지정된 형식은 필드에서 보유하는 리소스를 해제하는 일을 담당하지 않습니다. 즉, 형식에 ‘삭제 소유권’이 없습니다.
- Dispose에 대한 호출은 규칙 검사보다 깊은 호출 수준에서 발생합니다.
- 필드의 삭제 소유권은 포함하는 형식에서 보유하지 않습니다.
경고 표시 안 함
단일 위반만 표시하지 않으려면 원본 파일에 전처리기 지시문을 추가하여 규칙을 사용하지 않도록 설정한 후 다시 사용하도록 설정합니다.
#pragma warning disable CA2213
// The code that's violating the rule is on this line.
#pragma warning restore CA2213
파일, 폴더 또는 프로젝트에 대한 규칙을 사용하지 않도록 설정하려면 구성 파일에서 심각도를 none
으로 설정합니다.
[*.{cs,vb}]
dotnet_diagnostic.CA2213.severity = none
자세한 내용은 방법: 코드 분석 경고 표시 안 함을 참조하세요.
예시
다음 코드 조각에서는 IDisposable을 구현하는 형식 TypeA
를 보여 줍니다.
public class TypeA : IDisposable
{
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// Dispose managed resources
}
// Free native resources
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Disposable types implement a finalizer.
~TypeA()
{
Dispose(false);
}
}
다음 코드 조각은 필드에 대해 Dispose를 호출하지 않고 필드 aFieldOfADisposableType
을 삭제 가능한 형식(TypeA
)으로 선언하여 규칙 CA2213을 위반하는 형식 TypeB
를 보여 줍니다.
public class TypeB : IDisposable
{
// Assume this type has some unmanaged resources.
TypeA aFieldOfADisposableType = new TypeA();
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
// Dispose of resources held by this instance.
// Violates rule: DisposableFieldsShouldBeDisposed.
// Should call aFieldOfADisposableType.Dispose();
disposed = true;
// Suppress finalization of this disposed instance.
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}
public void Dispose()
{
if (!disposed)
{
// Dispose of resources held by this instance.
Dispose(true);
}
}
// Disposable types implement a finalizer.
~TypeB()
{
Dispose(false);
}
}
위반 문제를 해결하려면 삭제 가능한 필드에 대해 Dispose()
를 호출합니다.
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
// Dispose of resources held by this instance.
aFieldOfADisposableType.Dispose();
disposed = true;
// Suppress finalization of this disposed instance.
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}
참고 항목
.NET