다음을 통해 공유


using 문과 using 선언 관련 경고 해결

이 문서에서는 다음 컴파일러 오류를 다룹니다.

  • CS0245: 소멸자 및 object.Finalize는 직접 호출할 수 없습니다. 사용 가능한 경우 IDisposable.Dispose을/를 호출하는 것이 좋습니다.
  • CS0728: using 또는 lock 문의 인수인 지역 변수에 잘못된 할당이 있을 수 있습니다. 호출 또는 잠금 해제는 Dispose 로컬의 원래 값에서 발생합니다.
  • CS1674: using 문에 사용되는 형식은 암시적으로 ''System.IDisposable로 변환할 수 있어야 합니다.
  • CS8410: 비동기 using 문에 사용된 형식은 암시적으로 'System.IAsyncDisposable'로 변환 가능하거나 적합한 'DisposeAsync' 메서드를 구현해야 합니다.
  • CS8417: 비동기 using 문에 사용되는 형식은 'System.IAsyncDisposable' 또는 'DisposeAsync' 메서드를 구현해야 합니다. 'await using'가 아니라 'using'를 의미했나요?
  • CS8418: using 문에 사용되는 형식은 ''System.IDisposable을 구현해야 합니다. 'using'이 아니라 'await using'를 의미했나요?
  • CS8647: using 변수는 스위치 섹션 내에서 직접 사용할 수 없습니다(중괄호 사용 고려).
  • CS8648: using 선언 후에는 goto 위치로 이동할 수 없습니다.
  • CS8649: A는 goto 동일한 블록 내에서 using 선언 전에 위치로 이동할 수 없습니다.
  • CS9229: 선언을 사용하여 한정자를 배치할 수 없습니다.

IDisposable 및 IAsyncDisposable 구현

다음 컴파일러 오류 및 경고는 삭제 패턴 구현 또는 사용과 관련된 문제를 나타냅니다.

  • CS0245: 소멸자와 object.Finalize는 직접 호출할 수 없습니다. IDisposable.Dispose을(를) 사용할 수 있는 경우, 이를 호출하는 것이 좋습니다.
  • CS1674: using 문에 사용되는 형식은 암시적으로 ''System.IDisposable로 변환할 수 있어야 합니다.
  • CS8410: 비동기 using 문에 사용되는 형식은 암시적으로 'System.IAsyncDisposable'로 변환하거나 적절한 'DisposeAsync' 메서드를 구현해야 합니다.
  • CS8417: 비동 using 기 문에 사용되는 형식은 ''를 구현하거나 적절한 'System.IAsyncDisposableDisposeAsync' 메서드를 구현해야 합니다. ''가 아니라 'usingawait using'를 의미했나요?
  • CS8418: using 문에 사용되는 형식은 ''System.IDisposable을 구현해야 합니다. ''가 아니라 'await usingusing'를 의미했나요?

using 문은 블록 끝에서 using 리소스를 적절하게 폐기하도록 합니다. using 문에서 형식을 사용하려면 적절한 처리 인터페이스를 구현해야 합니다. 동기 using 문의 경우, 형식은 IDisposable을(를) 구현해야 합니다. 비동기 await using 문의 경우, 형식이 IAsyncDisposable를 구현해야 합니다.

  • Finalize를 직접 호출할 수 없음(CS0245): 소멸자 또는 Object.Finalize 메서드를 직접 호출할 수 없습니다. 가비지 수집기는 개체가 더 이상 참조되지 않을 때 파이널라이저를 자동으로 호출합니다. 결정적 정리를 위해 대신 메서드를 IDisposable 구현 Dispose 하고 호출합니다.
  • 형식은 IDisposable(CS1674)을 구현해야 합니다. IDisposable을(를) 구현하는 형식만 using 문에서 사용할 수 있습니다. 값 형식은 이 인터페이스를 구현하지 않으며 적절한 제약 조건이 없는 제네릭 형식 매개 변수는 삭제 가능한 것으로 간주할 수 없습니다. 제네릭 형식을 사용할 때와 같이 where T : IDisposable 형식 제약 조건을 적용합니다.
  • 형식은 IAsyncDisposable(CS8410)을 구현해야 합니다. 함께 await using 사용되는 형식은 적절한 IAsyncDisposable 메서드를 구현 DisposeAsync 하거나 제공해야 합니다. 형식이 비동기 삭제를 지원하지 않는 경우, using 동기 문을 대신 사용하거나 필요한 인터페이스를 구현합니다.
  • 일치하지 않는 처분 패턴(CS8417, CS8418): CS8417은 IDisposable만 구현하는 형식과 await using를 함께 사용할 때 발생합니다. CS8418은 using을(를) 지원하지 않고 오직 IAsyncDisposable만 구현하는 형식을 동기식으로 사용할 때 발생합니다. using 키워드를 형식이 구현하는 인터페이스에 맞추거나, 두 패턴을 모두 지원해야 하는 경우 두 인터페이스를 모두 구현합니다.

자세한 내용은 파이널라이저, Dispose 메서드 구현, DisposeAsync 메서드 구현을 참조하세요.

변수 범위 및 제어 흐름 사용

다음 컴파일러 오류 및 경고는 제어 흐름 문 내에서 변수를 using 잘못 사용하는 것과 관련이 있습니다.

  • CS0728: using 또는 lock 문에 대한 인수인 지역 변수에 잘못된 할당이 있을 가능성이 있습니다. 이러한 호출 또는 잠금 해제는 지역 변수의 원래 값에 대해 수행됩니다.
  • CS8647: using 변수는 스위치 섹션 내에서 직접 사용할 수 없습니다(중괄호 사용 고려).
  • CS8648: using 선언 후에는 goto 위치로 이동할 수 없습니다.
  • CS8649: A는 goto 동일한 블록 내에서 using 선언 전에 위치로 이동할 수 없습니다.

선언된 using 변수에는 리소스 누출을 방지하는 특정 범위 지정 규칙이 있습니다. 컴파일러는 적절한 삭제를 보장하기 위해 이러한 규칙을 적용합니다.

  • 변수에 값 할당(CS0728): 이 경고는 using 문에서 리소스로 사용되는 변수에 새 값을 할당했다는 것을 나타냅니다. 삭제 호출은 리소스 누수로 이어질 수 있는 새로 할당된 값이 아닌 원래 값에서 발생합니다. 리소스를 나중에 할당하는 대신 문장 선언에서 using 를 초기화합니다.

  • 스위치 섹션에서 변수 사용(CS8647): using 선언은 범위의 끝에 삭제되는 변수를 만듭니다. 중괄호 없이 스위치 섹션에서 직접 사용하는 경우 범위가 모호하며 오류가 발생할 수 있습니다. 스위치 섹션 콘텐츠를 중괄호로 래핑하여 범위를 명확하게 정의합니다.

  • Goto 문 및 사용 선언(CS8648, CS8649): goto 문으로 using 선언을 뛰어넘는 것은 적절한 리소스 관리를 건너뛰기 때문에 사용할 수 없습니다. CS8648은 using 선언을 앞으로 점프할 때 발생하며, CS8649는 using 선언 이전의 위치로 뒤로 점프할 때 발생합니다. 루프와 같은 구조화된 제어 흐름을 사용하도록 코드를 재구성하거나 점프 대상 외부로 선언을 using 이동합니다.

자세한 내용은 using 문을 참조하세요.

잘못된 using 선언

  • CS9229: 선언을 사용하여 한정자를 배치할 수 없습니다.

using 선언에 포함된 변수 선언은 다음 수정자를 포함할 수 없습니다.

  • const
  • static
  • volatile
  • readonly
  • 접근성 한정자: public, protected, internal, private, protected internal또는 private protected

다음 예제에서는 CS9229를 생성합니다.

using System;

class Program
{
    static void Main()
    {
        // error CS9229: Modifiers cannot be placed on using declarations.
        public using var resource = new Resource();
        
        // error CS9229: Modifiers cannot be placed on using declarations.
        static using var anotherResource = new Resource();
    }
}

class Resource : IDisposable
{
    public void Dispose() { }
}

이 오류를 해결하려면 선언에서 using 한정자를 제거합니다.

using var resource = new Resource();

자세한 내용은 using 문을 참조하세요.