[C#] 소멸자를 언제 만들어야합니까?

예를 들면 다음과 같습니다.

public class Person
{
    public Person()
    {
    }

    ~Person()
    {
    }
}

언제 소멸자를 수동으로 만들어야합니까? 소멸자를 언제 만들어야 했습니까?



답변

업데이트 :이 질문은 2015 년 5 월 내 블로그의 주제였습니다 . 좋은 질문 감사합니다! 사람들이 일반적으로 마무리에 대해 믿는 많은 허위 목록은 블로그를 참조하십시오.

언제 소멸자를 수동으로 만들어야합니까?

거의 없다.

일반적으로 클래스가 객체가 사라질 때 정리해야하는 고가의 관리되지 않는 리소스를 보유하고있을 때 소멸자를 만듭니다. 자원을 정리하려면 일회용 패턴을 사용하는 것이 좋습니다. 그러면 소멸자는 객체의 소비자가 폐기하는 것을 잊어 버린 경우에도 리소스가 결국 정리된다는 보증입니다. (아마도.)

소멸자 를 매우 조심스럽게 만들고 가비지 수집기가 작동하는 방식을 이해하는 경우 . 소멸자는 정말 이상합니다 :

  • 그들은 스레드에서 실행되지 않습니다. 그들은 자신의 스레드에서 실행됩니다. 교착 상태를 유발하지 마십시오!
  • 소멸자로부터 처리되지 않은 예외가 발생하면 나쁜 소식입니다. 자체 스레드에 있습니다. 누가 잡을까요?
  • 생성자가 시작된 생성자가 완료 되기 전에 객체에서 소멸자가 호출 될 수 있습니다 . 올바르게 작성된 소멸자는 생성자에 설정된 불변에 의존하지 않습니다.
  • 소멸자는 객체를 “복구”하여 죽은 객체를 다시 살릴 수 있습니다. 정말 이상합니다. 하지마
  • 소멸자는 절대 도망 가지 않을 것입니다. 완료 예정인 개체에 의존 할 수 없습니다. 아마 그럴 입니다, 그러나 그것은 보증이 아닙니다.

소멸자에서 일반적으로 사실 인 것은 거의 없습니다. 정말 조심하세요. 올바른 소멸자를 작성하는 것은 매우 어렵습니다.

소멸자를 언제 만들어야 했습니까?

소멸자를 처리하는 컴파일러 부분을 테스트 할 때. 나는 프로덕션 코드에서 그렇게 할 필요가 없었습니다. 관리되지 않는 리소스를 조작하는 개체는 거의 작성하지 않습니다.


답변

이를 “완료 자”라고하며 일반적으로 상태 (예 : 필드)에 관리되지 않는 리소스 (예 : p / invoke 호출을 통해 검색된 핸들에 대한 포인터)가 포함 된 클래스에 대해 하나만 작성해야합니다. 그러나 .NET 2.0 이상에서는 실제로 관리되지 않는 리소스 정리를 처리하는 더 좋은 방법 인 SafeHandle이 있습니다. 이를 감안할 때, 파이널 라이저를 다시 작성할 필요는 없습니다.


답변

클래스가 Windows 파일 핸들과 같은 관리되지 않는 리소스를 유지 관리하지 않는 한 필요하지 않습니다.


답변

소멸자 / 완료 기라고하며 일반적으로 Disposed 패턴을 구현할 때 생성됩니다.

클래스의 사용자가 Dispose를 호출하는 것을 잊어 버리고 (최종적으로) 리소스가 해제되도록하는 소멸 솔루션이지만 소멸자가 호출되는 시점에 대한 보장은 없습니다.

스택 오버플로 질문 에서 허용 된 답변은 폐기 패턴을 구현하는 방법을 올바르게 보여줍니다. 가비지 수집기가 자체 정리하지 않는 처리되지 않은 리소스가 클래스에 포함 된 경우에만 필요합니다.

좋은 방법은 클래스의 사용자에게 리소스를 수동으로 처리하여 리소스를 즉시 해제 할 수있는 가능성을 부여하지 않고 종료자를 구현하지 않는 것입니다.


답변

관리되지 않는 리소스가 있고 개체가 없어 질 때 리소스가 정리되도록해야합니다. COM 개체 또는 파일 처리기가 좋은 예입니다.


답변

객체를 WPF 응용 프로그램 범위의 메모리에서 제거했는지 확인하기 위해 소멸자 (디버그 목적으로 만)를 사용했습니다. 가비지 수집이 실제로 개체를 메모리에서 제거하는지 확실하지 않았으므로 확인하는 것이 좋습니다.


답변

소멸자는 클래스에 캡슐화되어있는 관리되지 않는 리소스를 해제하는 암시 적 방법을 제공합니다. GC가 리소스를 가져 오면 호출되며 기본 클래스의 Finalize 메서드를 암시 적으로 호출합니다. 관리되지 않는 많은 리소스를 사용하는 경우 IDisposable 인터페이스를 통해 해당 리소스를 해제하는 명시적인 방법을 제공하는 것이 좋습니다. C # 프로그래밍 가이드를 참조하십시오 : http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx