2010-01-29 4 views
6

나는 그 클래스의 인스턴스를 처리해야하는 클래스가 있습니다. 또한 이러한 인스턴스를 단독으로 생성하거나 여러 인스턴스를 생성하는 여러 클래스가 있습니다.Disposable 인스턴스 목록을 반환하는 메서드를 사용해야합니까?

내 방법에서 IList<MyClass>을 반환해야합니까? 또는 MyClassCollection 인 일회용 클래스를 만들어야합니까?

편집 :

묻는에 대한 나의 주된 이유는 내가이 꽤 많은 일을 만난다이다 :

IList<MyObject> list = GetList(); 
foreach(MyObject obj in list) 
{ 
    //do something 
    obj.Dispose(); 
} 

을 그리고 내가 일을 더 나은 것으로 보인다

using (IList<MyObject> list = GetList()) 
{ 
    foreach(MyObject obj in list) 
    { 
    //do something 

    } 
} 
+0

첫 번째 예제는 더 이상 필요없는 개체를 처리하지만 두 번째 예제는 전체 반복이 완료 될 때까지 개체를 유지합니다. 이 두 가지 방법으로 개체를 처리 할 수 ​​있으며,이를 기반으로 사용할 방법을 선택해야합니다. –

답변

1

컨테이너 클래스는이 인스턴스에서 더 깨끗합니다. 그런 다음 표준 컬렉션 클래스를 계속 사용할 수 있습니다. 그러면 항목의 끝에 처분해야 할시기를 더 분명하게 명시해야합니다.

public class ListScope : IDisposable 
{ 
    private IList list; 
    public ListScope(IList list) 
    { 
     this.list = list; 
    } 

    #region IDisposable Members 

    public void Dispose() 
    { 
     foreach (object o in this.list) 
     { 
      IDisposable disposable = (o as IDisposable); 
      if (disposable != null) 
        disposable.Dispose(); 
     } 
    } 

    #endregion 
} 

과 같이 사용할 수 있습니다

getList().DoStuffAndDisposeElements (x => doStuff(x)); 

하지 :

static class Extensions 
{ 
public static void DoStuffAndDisposeElements<T> (this List<T> list, Action<T> action) 
{ 
     list.ForEach (x => { action (x); 
       IDisposable disposable = (x as IDisposable); 
       if (disposable != null) 
        disposable.Dispose(); 

     }); 
} 


} 

하는 당신에 의해 호출 할 수 있습니다 당신이 원하는 경우에 당신은 또한 확장을 사용할 수

using (new ListScope (list)) 
{ 
    // Do stuff with list 
} 
+0

왜 if (o는 IDisposable) {(o는 IDisposable로) 사용하고 있습니까? Dispose(); } '? 왜 'o IDisposable'을 사용하고 null을 테스트하지 않는가? – thecoop

+0

@thecoop 나는 그 접근법에서 얻을 수있는 것을 정말로 보지 못했다. ID는 임시 변수를 사용하거나 if (IDisposabe)! = null) {(IDisposable로) .Dispose()}와 같이 사용해야합니다. 나는이 방법이 더 깨끗하다고 ​​느낀다. 그러나 어느 쪽이라도 사용하기 위해 자유롭게 느낀다, 나는 dores가 그것에서 정말로 많이 생각하지 않는다. :) –

+0

나는 double (o IDisposable)이 불필요한 반복 된 캐스트를 피하기 위해 변수를 만들어야한다는 정적 코드 분석 규칙을 틱한다고 생각합니다. (맞습니까?) – peSHIr

2

사용 방법에 따라 두 가지 모두 합리적인 옵션이 될 수 있습니다. 모든 객체를 동시에 처분해야한다는 것을 알고 있다면 목록을 일회용으로 만드는 것이 좋습니다. 그러나 객체의 수명이 다를 수 있다면 일반 목록을 반환 할 것입니다.

아마도 where T : IDisposable에 제약 조건이 적용된 IDisposableList<T>을 만들고 클래스에 IDisposable을 구현하려면 모든 요소에 Dispose을 호출하면됩니까? 그런 다음 모든 다른 IDisposable 유형에 대해이 클래스를 재사용 할 수 있습니다.

+0

내가하고 싶은 것을 보여주기 위해 내 질문을 편집했습니다. –

+0

@bebop : 내가 처분하는 목록을 선택하면 현재 상황에 대해 조금 더 편리하다고 생각하지만 클라이언트는 항상 처분해야한다고 암시하고 있습니다 개체를 동시에 객체를 동시에 폐기해야하는 근본적인 이유가 있습니까? 대신 하나의 리소스를 폐기해야하는 대신 다른 방법으로 모델링 할 수 있습니까? 귀하의 상황은 연결 및 거래 또는 독자가 많은 파일을 생각 나게합니다. 아마도 이러한 수업을 설계에 영감으로 사용할 수 있을까요? –

2

Dispose() 메소드를 호출하는 것은 클라이언트 코드에 따라 달라집니다. 객체를 사용하여 작업이 완료된 시점 만 알 수 있습니다. 코드가 어떻게 생겼는지 모르기 때문에 어떤 식으로도 도움을 줄 수 없습니다. 요소를 처리하는 목록 객체를 만드는 것은 좋은 생각이 아닙니다. 프레임 워크에는이 작업을 수행하는 콜렉션 객체가 없습니다. 클라이언트 코드 프로그래머를 혼란스럽게 할뿐입니다.

+1

재미 있습니다. 목록의 일부 요소가 다른 메서드로 반환 된 다음 목록을 삭제하면 문제가 발생할 수 있다고 생각합니다. –

1

당신이 그걸로 얼마를 얻겠습니까,하지만 거기에 Y가 유용 할 상황 일)

+0

.net 2.0,하지만 제안 주셔서 감사합니다. –

3

오히려 목록보다)는 순서를 항목의 (IEnumerable<T>을 생성하는 것이 더 쉬울 수 있습니다 - 당신이 반복자로 묶어 각각의 수명을 만들 수있는 방법이 있습니다, 그래서 :

  • 당신은 한 번에 하나가 자신의 시간이 다
  • 모두도 오류, 배치받을 때 그들이 배치 얻을
  • (나는 그들이 비싼 가정)

이 항목은 LINQ를 사용하여 here을 탐색 한 주제이지만 소스가 시퀀스 인 경우 다른 방법도 있습니다.

관련 문제