2014-03-04 1 views
0

이 SomeDisposable의 팩토리 실제로 래퍼한다는 IDisposable :: 폐기()

public class Wrapper : SomeDisposable 
{ 
    public new /*:(*/ Dispose() { ... }; 
} 

워치 독의 종류를 반환/창조라고 가상하고 발신자는 Wrapper.Dispose()

using (SomeDisposable sd = SomeDisposableFactory.Create(...)) 
{ 
} // Wrapper.Dispose() never called. 

처럼 사용 결코 부르지 않았다. Dispose()이 가상이면 Wrapper.Dispose()이 호출됩니다.

인터페이스는 다른 모범 사례 방법 virtual Dispose(bool)이 실제로 존재하거나 실제로는 존재할 수 없도록 (권장되는 패턴 일뿐) 가상으로 구현되도록 보장하지 않습니다. 인터페이스는 현재 가상의 제약을 허용하지 않습니다.

이 특정 딜레마를 해결했을 권장 패턴 Dispose()을 만들지 않은 것에 대한 찬반론은 무엇입니까? C#에서는 인터페이스를 통해 가상 메서드를 강제 적용 할 수 있어야합니다 (추상 클래스는 계약 정의로 널리 사용되지 않으므로).

+0

new' 거의 항상 나쁜 생각 '사용. 코드 분석을 사용하는 경우 실제로 Disse (bool) 메소드를 포함하여이 패턴을 검사하는 * IDisposable을 올바르게 구현하는 경고가 있습니다. http://msdn.microsoft.com/en-us/library/ms244737.aspx –

+0

Found [중복] (http://stackoverflow.com/questions/3619490/why-should-dispose-be-non-virtual) – crokusek

답변

2

아니요. 실제로 패턴은 Dispose() (가상이 아님)은 protected virtual void Dispose(bool) 메서드를 호출해야한다고 말합니다. 이렇게하면 기본 클래스 Dispose 호출이 계층 구조를 제대로 전달할 수 있습니다.

IDisposable에 대한 문서에서 철자 :

  • 그것은 하나 개의 공용을 제공해야한다, 가상이 아닌 폐기() 메서드 보호 된 가상 폐기 (부울 폐기)하는 방법.
  • Dispose() 메서드는 Dispose (true)를 호출하고 성능을 위해 종료를 억제해야합니다.
  • 기본 형식에는 마무리 도구가 없어야합니다.
+0

"should"및 "must 's"문서에서 지정/시행 할 수 있기를 원하는 경우이 대답 허용 C# 자체. – crokusek

0

이것은 이미 해결되었습니다. 있습니다

일회용 유형 sealed는 일반적인 dispose pattern 사용해서는 안 :

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) 
     { 
      // dispose managed resources. 
      if (resource != null) resource.Dispose(); 
     } 

     // free unmanaged resources. 
    } 
} 
+2

많이 봅니다. 이것은 사람들이 반드시 필요하지 않은 곳에 파이널 라이저를 사용하도록 권장합니다. 클래스에 관리되지 않는 리소스가있는 경우에만 파이널 라이저를 사용해야한다고 설명해야합니다. 파이널 라이저를 추가하면 오브젝트가 자동으로 수명이 긴 오브젝트로 만들어지고 가비지 콜렉터의 레벨 1 세대 오브젝트 이상으로 항상 올라 가게됩니다. – stevethethread

+0

@stevethethread 우수 포인트. 파생 클래스는 필요에 따라 고유 한 파이널 라이저를 정의 할 수 있습니다. –

+1

@stevethethread 귀하의 요점은 유효 할 수 있습니다,하지만 왜 내가 관리되지 않는 리소스가없는 경우'IDisposable' 구현하고 싶어? –