2010-12-30 2 views
5
interface IMyInterace 
{ 
void Open(); 
object Read(); 
void Close(); 
} 

class MyImplementation : IMyInterface 
{ 
public void Open() { /* instantiates disposible class */ } 
//... 
public void Close() { /* calls .Dispose(); */ } 

} 

클래스 내부의 삭제 가능한 인스턴스가 호출되도록 이러한 유형의 상황을 처리하는 좋은 방법이 있습니까? IMyInterface 구현은 반드시 IDisposible 인스턴스를 캡슐화하지 않고 닫히고 응용 프로그램의 수명이 다할 때까지 반복적으로 다시 열립니다. (호출자가 문서에서 제외하고 '닫기'를 호출해야한다는 신호는 없습니다.)일회용 인스턴스를 캡슐화하는 것보다 클래스를 다루는 방법은 무엇입니까?

나는 이렇게 생각 해요 :

  • 는 MyImplementation에 IDisposible를 구현합니다.
  • Dispose()를 설정하여 Close()를 호출합니다.
  • 호출이 닫혔는지 확인하기 위해 열기 시작 열기에 대한 호출을 Close() 또는 Dispose()에 추가하십시오.

IMyInterface의 사용자는 사용중인 구현을 알지 못하므로 MyImplementation을 일회용으로 만드는 것이 얼마나 중요한지 잘 모르겠지만 모든 구현이 IDisposibles를 캡슐화하지는 않습니다.

답변

1

:이 클래스는 자주 (/ 때로는

경우

단순히 인터페이스를 구현하는 것보다 더 복잡하다, 전체 일회용 패턴을 따르십시오) 혼자 인터페이스를 통해 내가 IDisposable에서 IMyInterace를 상속 조언을 사용합니다.

이렇게하면 사용자가 이러한 개체를 일관된 방식으로 사용할 수 있습니다. 단점은 당연히 실제로 필요하지 않은 클래스에 Dispose 메서드를 추가해야 할 수도 있습니다. 그러나 이점은 일관성과 유연성에 있습니다. 클래스가 미래에 변경되어 Dispose()가 필요하면 어떻게해야합니까?

최소한의 접근 방식 :

interface IMyInterace : IDisposable { } 

sealed class MyImplementation : IMyInterface 
{ 
    public void Open() { /* instantiates disposible class */ } 

    public void Close() { /* calls _myField.Dispose(); */ } 

    public void Dispose() { Close(); } // only use this short form in a sealed class 

} 
5

이 문제를 처리하는 표준 방법은 간단히 MyImplementationIDisposable을 구현하는 것입니다.

3

John이 언급했듯이 첫 번째 글 머리 기호는 바로 위에 있습니다.

때때로 Close() 메서드는 기능적으로 Dispose()과 동의어이며 추상화와의 의미 론적 일관성을 유지하기 위해 존재합니다. 즉, Open() 메소드를 보완하는 것입니다. 다른 번, Close() 다시 열 수 있지만 Dispose()하지 않아야합니다. 따라서 두 번째 글 머리 기호는 괜찮습니다.

배치 된 객체를 재사용해서는 안되기 때문에 글 머리 기호 3을 반드시 적용 할 필요는 없습니다. Open()에 다시 전화해야하는 경우 새 인스턴스를 사용해야합니다. 사실 Open() 메서드는 부울 플래그를 검사하여 Dispose()이 호출 된 후 ObjectDisposedException을 던져야합니다. 객체가 닫힌 후에 다시 열 수 있도록하려면 없이 Open()이 호출 된 경우 예외를 던지거나 Debug.Assert()을 사용하는 것이 좋습니다. 이렇게하면 이러한 인스턴스를 제대로 관리하지 못할 수 있습니다.

이미 대답을 여기에 추가
bool disposed; 

public void Dispose() // don't make virtual! 
{ 
    Dispose(true); 
    GC.SuppressFinalize(this); 
} 

protected virtual void Dispose(bool disposing) 
{ 
    if(!disposed) 
    { 
     if(disposing) 
     { 
      // dispose of managed resources here, for example: 
      // if(resource != null) { resource.Dispose(); } 
     } 
    } 

    // dispose of unmanaged resources here 

    disposed = true; 
} 
+2

당신은 전체 일회용 패턴을 필요가 없습니다.소멸자가 필요하지 않으므로 SuppressFinalize가 필요하지 않습니다. –

관련 문제