2017-10-11 16 views
1

Microsoft design guidelines 언급 폐기 패턴과 시나리오 사용 방법 :다른 IDisposable 객체를 참조하는 유형의 기본 패턴을 처리해야합니까?

이 일회용 형식의 인스턴스를 포함하는 유형의 기본 폐기 패턴을 구현 마십시오. 기본 패턴에 대한 세부 사항은 인 기본 배출 패턴 섹션을 참조하십시오. 다음과 같이

나중에, 그들은 기본 폐기 패턴을 보여

  1. 왜 우리가 그냥 경우 폐기 (BOOL)를 구현해야합니까 : 있습니다

    public class DisposableResourceHolder : IDisposable { 
    
        private SafeHandle resource; // handle to a resource 
    
        public DisposableResourceHolder(){ 
         this.resource = ... // allocates the resource 
        } 
    
        public void Dispose(){ 
         Dispose(true); 
         GC.SuppressFinalize(this); 
        } 
    
        protected virtual void Dispose(bool disposing){ 
         if (disposing){ 
          if (resource!= null) resource.Dispose(); 
         } 
        } 
    } 
    

    질문 매개 변수가 true 인 단일 호출? 매개 변수가없는 Dispose() {resource?.Dispose();}으로 쉽게 간단하게 만들 수 있습니다. 참조하는 객체가 관리되고 자체 finalizer가 있으므로 여기에 finalizer가 필요하지 않으므로 누출되지 않습니다.

  2. finalizer가 없는데 GC.SuppressFinalize(this)으로 전화하는 것이 좋습니다. GC는 존재하지 않기 때문에 어쨌든 파이널 라이저를 호출하지 않을 것입니다!
  3. Dispose (bool)의 필요성을 알 수있는 유일한 경우는 IDisposable이나 finalizer (this article에 표시된 것과 같이)를 구현하지 않는 관리되지 않는 참조가 실제로있는 경우입니다. 그러나 bool disposing의 의미는 bool includingManagedResources입니다. 그렇다면 왜 그것이 실제로 그렇게해야하는지에 대해 오도 된 '처분'을하는 이유는 무엇입니까?
+1

그렇지 않습니다. Microsoft는 finalizers가있는 클래스를 작성 했으므로 이러한 문제에 대해 걱정했습니다. 나만의 파이널 라이저 작성하지 마십시오. Microsoft가 SafeHandle 클래스를 만들 때까지 기다렸습니다. –

+1

이 패턴의 추론은 클래스에서 상속받을 수 있으며 상속 된 클래스는 finalizer를 가질 수 있습니다. 그리고 아니오 - 당신은 이것을 할 필요가 없습니다. – Evk

+0

@Evk는 실제로 의미가 있습니다 ... 감사합니다! –

답변

1
  1. 다른 클래스는 클래스에서 상속 할 수있다. 또한 파생 클래스가 관리되지 않는 리소스 (권장되거나 포함되지 않음)를 보유한다는 것을 고려하면이 클래스는 Dispose(false)을 호출하는 종료자를 추가해야합니다. 수업이 인봉 되었다면 나는 너와 동의 할 것이다.

  2. void Dispose() 메서드는 Microsoft의 지침에 따라 virtual이 아니어야하므로 클래스를 파생하면 클래스를 처리 한 후에 종료를 억제 할 수 없습니다. 구현에 파이널 라이저가 필요하지 않을 수도 있지만 클래스를 파생시키는 것이 좋습니다.

  3. 제 생각에는 특별한 이유없이 disposing입니다. 나는 개인적으로 그것을 또한 개명 할 것입니다.

어쨌든 내 관점에서는 관리되는 리소스와 관리되지 않는 리소스를 섞어 사용하는 것은 좋지 않습니다. 이미 주석에서 언급했듯이 Microsoft는 심지어 관리되지 않는 리소스를 관리되는 리소스로 캡슐화하여 finalizer를 구현해야하는 경우가 거의없는 경우를 권장합니다. 나는 내가 마지막으로 이것을했을 때 기억이 안납니다.

오해의 소지가있는 이름 지정이나 이해하기 어렵다는 이유로 여러 가지 이유로 구현 지침을 고수하지 않습니다. 다른 접근 방식은 this answer입니다.

+0

품목 2 필요 [표창장 필요]. 클래스가 Disposable 패턴을 구현하는 경우에만 가상 객체가 아니어야한다는 것을 알 수있는 유일한 방법입니다. –

+0

@HansPassant 원래 링크 된 문서에는 "매개 변수없는 Dispose 메서드를 가상으로 만들지 마십시오."라는 내용이 이미 나와 있습니다. 편집 : 이제 귀하의 의견을 이해하는 것 같아요. 물론 가상 처분 메소드를 작성하는 것은 금지되어 있지 않습니다. 참조 된 문서와 관련하여 권장되는 방법이 아닙니다. 이 지침에 충실하지 않은 내가 추가 한 대체 접근법은 다르게 적용됩니다. – Peit

+0

맞아요, 일회용 패턴에 대해서만 합리적인 조언, 폐기 (bool) 이미 가상입니다. 패턴을 사용하지 않을 때는 괜찮습니다. 클래스를 봉인한다고 선언하지 않는 한 추천합니다. –