【问题标题】:Will dispose be called for anonymous variables?会为匿名变量调用 dispose 吗?
【发布时间】:2009-04-29 17:17:50
【问题描述】:

例如,

int myResult= (new UnmanagedResourceUsingMemorySuckingPig()).GetThingsDone(id);

没有 using 块,没有明显的方法来使用 using 块,没有明显的方法来调用 Dispose()。当然,UnmanagedResourceUsingMemorySuckingPig 确实实现了 IDisposable。

【问题讨论】:

  • 问题:UnmanagedResourceUsingMemorySuckingPig如果是非托管的,如何实现IDispose?
  • GetThingsDone() 似乎是“作恶者”的一个例子,我建议重新设计以删除它。参看。 steve-yegge.blogspot.com/2006/03/…
  • @Dave:如果您仔细阅读名称,它使用非托管资源,这并不意味着它本身是非托管的。

标签: c# idisposable anonymous-class


【解决方案1】:

如果该类的终结器调用Dispose(),是的。如果没有,不。

(编辑)只是一些additional info

不要假设 Dispose 会 叫。 a 拥有的非托管资源 类型也应该在一个 在以下情况下完成方法 未调用 Dispose。

编辑

为了澄清上述编辑,我看到很多人(在这个线程、SO 和其他地方)声称“当对象被删除时,GC 将调用 Dispose()。”根本不是这种情况。是的,编写组件的优秀的防御性编码器会假定Dispose() 不会被显式调用,并且会在终结器中这样做。但是,使用组件的优秀的防御性编码器必须假定终结器不会调用Dispose()垃圾收集器中没有自动调用Dispose()。仅当终结器调用 Dispose() 时,此功能才可用。

【讨论】:

  • @bruno:谢谢!我正在开车,而其他人正在发布他们的答案,因此非常感谢任何有助于揭穿 GC 自动调用 Dispose() 的神话的帮助!
  • 虽然终结器确实必须显式调用 Dispose,但我从未见过带有不调用 Dispose 的终结器的 Disposable 类。我不同意组件的用户应该假设终结器不调用 Dispose - 这无异于假设组件是错误的。尽管如此,我还是同意 Disposable 组件的用户应该调用 Dispose(通常使用 using 语句)。
  • @Joe:假设开发人员没有遵循 Microsoft 的指导方针之一。正如开发人员必须假定 Dispose() 不会被调用(这是设计准则),用户必须假定他必须调用它。
  • 感谢您的澄清。我删除了我的帖子以结束混乱。
【解决方案2】:

我不相信。你必须写:

 using (UnmanagedResourceUsingMemorySuckingPig urumsp = new UnmanagedResourceUsingMemorySuckingPig()) 
{
  myResult= urumsp.GetThingsDone(id);
}

【讨论】:

    【解决方案3】:

    您只能确定如果它有一个终结器(析构函数),那么它将被调用。 终结器可能会调用Dispose(),但通常的实现是终结器和Dispose() 都调用protected Dispose(bool)

    换句话说,它取决于 UnmanagedResourceUsingMemorySuckingPig 的实现,如果它遵循准则,那么匿名对象将被清理,但不如 using 块那么有效。

    【讨论】:

      【解决方案4】:

      没有。但是,GC 最终会收集对象并注意到它是可终结的(它是可终结的,对吗?)并将为您完成它。 Dispose 用于确定性地清理资源。

      【讨论】:

      • 大多数情况下是的,但是:这可能为时已晚(例如,如果您的代码想要在 GC 收集它之前使用非托管资源),并且并不总是有效 - 例如msdn.microsoft.com/en-us/library/… "由于实现限制,SearchResultCollection 类在垃圾回收时无法释放其所有非托管资源。"
      • 这是不正确的,就像另一个答案一样。 GC 中没有调用 dispose 的工具。如果终结器这样做(您必须明确编码),那么这是真的。如果终结器没有(如果你不告诉它它就不会),那么这不是真的。
      • @Adam:我没有说这个GC叫做Dispose,我说它终结了对象。
      • 这意味着这会反过来调用 Dispose(),不是吗?如果是这样,那么它不一定是真的。如果不是,那么这与问题有什么关系......?
      • 不,这当然不是暗示。我不确定你是怎么读的。它特别说“不”和“处置是为了确定性地清理资源”。 GC 不是确定性的。
      猜你喜欢
      • 2014-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-22
      相关资源
      最近更新 更多