2010-01-29 56 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

您的第一个示例在不再需要对象时立即释放对象,但第二个示例使对象保持活动状态,直到整个迭代完成。这是处理对象的两种不同方式,您应该根据哪种方法更合适地选择要使用的方法。 – 2010-01-29 10:00:36

回答

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 
} 

您可以使用如:

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

为什么使用'if(o is IDisposable){(o as IDisposable).Dispose(); }“?为什么不只是使用'o as IDisposable'然后测试null? – thecoop 2010-01-29 10:50:22

+0

@thecoop我真的不明白我会从这种方法中获得什么。 Id必须使用临时变量,或者如果((作为IDisposabe)!= null){(作为IDisposable).Dispose()}。我觉得这种方式更清洁,但也可以随意使用,我不认为它们真的很重要。 :) – 2010-01-29 11:45:42

+0

我认为一个double(o作为IDisposable)勾选了一个静态代码分析规则,并说你应该为此创建一个变量以避免不必要的重复转换。 (对吧?) – peSHIr 2010-01-29 13:40:43

2

这取决于你将如何使用它们,两者似乎都是合理的选择。如果你知道你需要同时处理所有的对象,那么也许让一次性清单变得有意义,但是如果对象可能有不同的生命周期,我只会返回一个普通的清单。

也许你可以做一个普通的IDisposableList<T>与约束对T where T : IDisposable,并有通过调用它的所有元素Dispose类实现IDisposable?然后,您可以重复使用此类,以获得您所有不同的IDisposable类型。

+0

编辑我的问题,举例说明我想要做的事 – 2010-01-29 09:43:43

+0

@bebop:我想如果你选择了可以处理的列表,那么对于你目前的情况来说可能会更方便一点,但是你暗示你的客户应该总是处理同时对象。是否有一个根本原因,为什么必须同时处理这些对象,并且可以通过拥有一种需要处理的资源来以不同的方式对其进行建模?你的情况让我想起了一些关联和交易,或者是一个有很多读者的文件。也许你可以用这些课程作为你设计的灵感? – 2010-01-29 09:47:34

2

调用Dispose()方法完全取决于客户端代码。只有它知道何时完成使用这些对象。你不能以任何方式提供帮助,因为你不知道代码的外观。创建处理元素的列表对象不是一个好主意。该框架不包含这样做的集合对象。你只会混淆客户端代码程序员。

+1

嗯有趣。我想可能会出现这样的情况:列表中的某些元素被返回到另一个方法,然后处置列表可能会导致问题 – 2010-01-29 09:46:05

1

你也可以使用一个扩展,如果你想:

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(); 

     }); 
} 


} 

,你可以通过调用肯定你会从中得到多少收益,但那里可能会有y为的情况下这将是有益的;)

+0

.net 2.0,但感谢您的建议 – 2010-01-29 12:57:29

3

它可能会更容易产生序列项IEnumerable<T>),而不是一个名单 - 有办法,你可以使每个扎成的迭代器的寿命,因此:

  • 你只有一次一个(我以为他们是昂贵的)
  • 他们得到处置时,他们的时间到了
  • 他们都得到处置,甚至在错误

这是我探索使用LINQ的here的主题,但也有其他方法,如果您的源是(或可能)是一个序列。

相关问题