【问题标题】:Setting an object to null within itself在自身内部将对象设置为 null
【发布时间】:2012-07-23 00:37:25
【问题描述】:

只是想知道这是否是一种可以接受的从内部终止对象的方式?自从

this = null;

不可能。我通常只是设置一个名为disposed 的布尔值或其他东西,如果在我终止它后访问该对象,则抛出异常。但后来这发生在我身上,我认为这可能是一个更清洁的解决方案,但它似乎有点 hacky,所以我想要第二个意见。我应该坚持设置一个布尔值还是继续这个。这也将允许垃圾收集器清理我的对象。

public class A
{
    public A()
    {

    }

    public void Method()
    {
        try
        {
            //Do Something.
        }
        catch
        {
            //If it fails destroy the object
            Destroy(this);
        }
    }

    private static void Destroy(A a)
    {
        a = null;
    }
}

【问题讨论】:

  • 一个不会“将对象设置为 null”,而是将 null 分配给以前可能是非 null 的 变量(或其他可变存储位置)。这反过来可能会使以前命名的对象不再强可达。

标签: c#


【解决方案1】:

a 是引用的副本。将它设置为null 随便你,它不会影响原始参考。现在你当然可以更改方法签名以通过ref 获取它的参数,但是你为什么要这样做呢?我无法想象您要在这里解决什么问题。

这也将允许垃圾收集器清理我的对象。

GC 不需要你设置对null 的引用,你没有用这个想法完成任何事情。你在捣乱参考文献的副本;该对象仍在内存中,并且 GC 足够聪明,可以知道给定引用是否有效,无论其当前值是否为null

有关详情,请参阅this SO thread

【讨论】:

  • 太棒了。我认为垃圾收集器只清理空对象。谢谢!
  • @Axis:那会比手动分配和释放要好一点(不?);)
  • @Axis 在大多数情况下,您根本不必担心 GC。在大多数情况下,一切都“正常工作”。您真正需要考虑这一点的唯一时间是,当您将处理程序从长期对象上的事件注册到短期对象中的处理程序时。
【解决方案2】:

如果您想要明确的、确定性的销毁,请实现接口 IDisposable 并在处理完对象后调用 Dispose。否则,一旦最后一个引用超出范围,垃圾收集器就会销毁该对象。 nulling 一个特定的 ref 不会触发集合。除非您确定必须这样做,否则不要再猜测垃圾收集器。

您的物品中有什么东西让您如此渴望尽快将其销毁?您绝对无法承受超过必要时间的资源很少而且介于两者之间 - 数据库连接、套接字、几百 MB 的内存块。对于那些,IDisposable 存在。其余的对象会在 GC 到达它们之前存活几毫秒;这就是垃圾收集世界的生活。在 2012 年,这被认为是可以接受的权衡。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多