【问题标题】:Standard Collection for IDisposable objectsIDisposable 对象的标准集合
【发布时间】:2010-11-12 07:51:54
【问题描述】:

我在查找表中有一堆IDisposable 对象(现在是普通的旧字典),但为了简化代码并避免错误,我正在寻找一个“拥有”它拥有的项目,并避免重新发明轮子 - 这样的类是否已经存在?

规范应该是: - 收藏品必须是一次性的,当它被丢弃时,所有包含的物品也应该被丢弃。 - 每当删除一个项目时,它首先是Dispose()-d。 - 理想情况下,集合将是通用的,类型约束强制执行所包含类型的IDisposable-ness。

我有点怀疑这样的课程是否存在,但我一直对 ReadOnlyCollectionObservableCollection 之前的存在感到惊喜......

基本上,我想要 C++ STL 容器的等价物,然后是 CLR ;-)。

【问题讨论】:

  • 已经有一段时间了。您是否制作了 IDisposableCollection?我也可以用。
  • 否;我最终包装了集合并只公开了我实际需要的(非常)少数方法 - 添加/获取/删除 - 以及我从事的特定工作的一些额外功能(大量文件系统观察者)。

标签: .net collections idisposable


【解决方案1】:

您正在寻找CompositeDisposable

    using System.Reactive.Disposables;

    ...

    CompositeDisposable xs = new CompositeDisposable(Disposable.Empty);
    xs.Add(Disposable.Empty);
    xs.Add(Disposable.Empty);
    xs.Dispose();

【讨论】:

  • 非通用。这不太理想。但也不是什么大问题。
  • Rx 扩展不是 .net 框架的一部分。虽然对许多人来说不是问题,但仅仅为一个微不足道的类引用整个库并不是一个好主意。
  • @arbiter 有一点,尽管恕我直言,不使用 Rx 没有多大意义。一旦您决定在项目中承担使用 .net 的巨大开销,就没有人应该为引入有用的库而争论不休。
【解决方案2】:

据我所知,IComponents 仅存在此类集合 - Container implements IContainer。对于通用 IDisposable,我认为您别无选择,只能“重新发明轮子”。

【讨论】:

  • 谢谢,我会调查一下(虽然它看起来有点重 - API 有很多我不会使用的东西 - 这可能没关系)!
  • Container 和 System.ComponentModel 对于一般用途来说似乎过于复杂且不够灵活。简而言之,我接受您的回答,即我别无选择,只能“重新发明轮子”。
【解决方案3】:

请记住,您的收藏可能不是唯一包含一次性物品的收藏... 如果另一个对象(集合外部)正在引用其中一个对象怎么办?如果你在集合被释放的时候就释放它,那么这个对象会发生什么?

如果这些对象为某些非托管资源清理实现了IDisposable,那么请确保它们也实现了终结并在那里处理非托管资源。

【讨论】:

  • 我目前完全控制对象和集合 - 所以这是一个假设的情况。在任何情况下;这就是 IDisposables 的工作方式,对吧?我的意思是,somebody 必须拥有(即最终处置)它们,在这种情况下,所有者碰巧拥有可变数量的 IDisposable,因此集合将是最简单的。
【解决方案4】:

这样的事情怎么样:

public class DisposableEnumerable<T> : IEnumerable<T>, IDisposable where T : IDisposable
{
    IEnumerable<T> Enumerable { get; }

    public DisposableEnumerable(IEnumerable<T> enumerable)
    {
        Enumerable = enumerable;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return Enumerable.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return Enumerable.GetEnumerator();
    }

    public void Dispose()
    {
        foreach(var disposable in Enumerable)
        {
            disposable.Dispose();
        }
    }
}

【讨论】:

  • 我认为在这里将惰性可枚举作为参数至少是棘手的;重要的是要知道您传入的对象确实已处置。当然,如果集合不修改也没关系。
  • 另外:即使它不应该发生,您也应该考虑如果底层Dispose() 抛出会发生什么。
【解决方案5】:

我明白你在问什么,但是在删除元素之前创建自己的删除方法有多难?

【讨论】:

  • 一点也不难——但如果可能的话,避免它会更干净。而且,不仅仅是移除,对 - 任何可能覆盖元素的方法都会隐式替换现有元素,这也需要 Dispose()'d。如果您的集合实现了一些标准接口,则这些删除/设置函数可能会有很多变体,从而导致代码膨胀。
猜你喜欢
  • 2014-02-15
  • 1970-01-01
  • 2011-07-16
  • 2010-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 2010-10-15
相关资源
最近更新 更多