【问题标题】:Do I need to Dispose items in a c# list before clearing it? [duplicate]在清除之前,我是否需要在 c# 列表中处理项目? [复制]
【发布时间】:2018-03-22 12:37:24
【问题描述】:

来自 list.Clear() 上的 MSDN 文档

Count 设置为 0,同时释放集合元素对其他对象的引用。

根据我所学到的(可能是错误的),处置和释放是不同的事情。 Disposed 意味着项目完全从内存中删除,release 意味着它根本没有通过指针绑定到该列表。

这是否意味着我需要这样做

foreach (var item in Items)
{
    item.Dispose();
}
this.Items.Clear();

如果我想彻底销毁/清除/释放/丢弃一个列表?

对我来说,这一切都应该像 .Clear() 一样简单,但是,我有点不清楚(双关语)这是否足够和正确。

请注意,我们没有覆盖 Dispose()Clear(),它们都是默认实现。

此外,列表是List<T>

编辑:根据评论建议,我已经检查过,这些项目都是IDisposables,这揭示了它们应该被丢弃的事实

重复澄清What is IDisposable for?

我不认为这两个问题是相同的,我的问题是问两件事之间的区别,另一个是要求澄清其中一件事。在我决定写这个问题之前,它也没有出现在我的搜索中,因为我过于关注“difference dispose vs clear”这样的关键字,这可能也是未来开发人员寻找答案的情况。我承认另一个答案提供了更多信息,并且是在此处添加的一个很好的链接。

【问题讨论】:

  • 如果没有更多的对象引用,它们将被收集。
  • Disposed 意味着任何非托管资源都被释放,根据IDisposable.Dispose。它与自动管理的内存完全无关。如果您的列表包含实现IDisposable 类型的对象,那么是的,您应该调用它。
  • 是的,如果您想处理它们,请处理它们。
  • 简短的回答是“视情况而定”。 Items 中有哪些项目?他们是怎么到那里的? 只有当您 100% 确定 Disposed 的对象没有在其他地方使用时,调用 Dispose 才是安全的。
  • 你需要引入和考虑“所有权”的概念。如果您的列表拥有这些对象,并且它们实现了IDisposable,那么是的,您需要在将它们从列表中删除之前处置这些对象。如果从列表中删除它们是转移所有权的行为,例如将它们添加到不同的列表中,那么不,在这种情况下,您不应该处置它们。您的这部分问题确实没有明确的答案。

标签: c# list memory dispose


【解决方案1】:

不,List<T>.Clear 没有 dispose 对象。如果你愿意,你可以写一个扩展:

public static class IEnumerableExtensions
{
    public static void DisposeAll<T>(this IEnumerable<T> seq) where T : IDisposable
    {
        foreach (T d in seq)
            d?.Dispose();
    }
}

var connections = new List<SqlConnection>();
// ...
connections.DisposeAll();

【讨论】:

  • 谢谢蒂姆!这是个好主意:)
【解决方案2】:

根据我所学到的(可能是错误的),处置和释放是不同的事情。

是的。

Disposed 意味着项目完全从内存中删除,release 意味着它根本没有通过指针绑定到该列表。

错了。 Disposed 意味着已完成与托管内存无关的对象所需的任何清理。

如果元素是IDisposable,那么在清除之前将它们全部Dispose()确实是一个好主意,如果它们通常通过该列表到达并且因此没有其他东西将Dispose()它们。

如果他们不是IDisposable,这不仅不需要,而且不可能。

如果它们是 IDisposable,但其他东西仍会使用这些元素,那么您不应该 Dispose() 它们,因为这会破坏其他用途。

【讨论】:

  • 谢谢乔恩,这很有帮助。它们确实是 IDisposable 并且只在那里使用,所以我应该保留该代码!
【解决方案3】:

据我所知,Dispose() 在某些方面非常有用,例如,如果您正在处理资源并且想要清除内存中的这些资源,或者如果发生任何异常,您肯定需要处理它。

提示:当您使用类似这样的语句代码时,您基本上不需要包含Dispose() 方法

using(var someResource = new SomeResource()){
    // Some galaxy logic here
}

因为它有 Dispose 机制。如果这些资源不是由CLR 管理的,那么只需使用using 语句将是一个简单的选择。


【讨论】:

    猜你喜欢
    • 2013-09-11
    • 1970-01-01
    • 2018-11-03
    • 1970-01-01
    • 2011-05-03
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多