在C#中引用已处置的对象

时间:2012-06-20 16:02:41

标签: c# dispose idisposable

如果这是一个愚蠢的问题,我很抱歉,但在您明确处理了一个对象后,您不应该再次引用该对象了......对吗?

示例:这通常是一个坏主意吗?

SomeObject o = new SomeObject();

o.DoStuff();

o.Dispose();

o.DoMoreStuff();

此外,是否有必要做这样的事情?

4 个答案:

答案 0 :(得分:2)

在您需要之前,您永远不会处置对象。处置对象意味着您不再需要它。当你不再需要这个物体时,你会将它丢弃(如果它是一次性的)。因此,处理后的对象永远不会被访问。

答案 1 :(得分:1)

处置对象会告诉它释放所有非托管资源,所以你必须问自己的问题是“如果没有这些资源,对象可以做任何有意义的事情”。这将取决于对象的细节。

大多数IDisposable个对象的设计使得如果在处理实例后尝试调用它们的方法,它们将抛出异常,或者更糟糕的是,只是做出意外的行为。

即使在被处置之后,其他对象仍然可以做有意义的事情。例如,DataTable实现了IDisposable,但有意义的数据往往存储在托管资源中,而不是非托管资源中。在其当前的实现中(可能会发生变化),它的Dispose方法不会执行任何操作,因此在处理之后使用它就可以了。 (话虽如此,当你还打算使用它时,没有令人信服的理由处理它。)

也可以想象一个对象在处理之后重新创建它需要的任何资源(这可能是一个坏主意,但仍然可能)。

说了这么多之后,专门设计一个你打算在它被处理之后使用的对象被认为是不好的做法,并且你也不会将它丢弃之前处理它的意图。完成它。这里的要点是,即使你不应该这样做,而且它经常会在你的脸上爆炸,这将是因为这是选择实施的类(如符合惯例)而不是因为它是技术要求。

答案 2 :(得分:0)

虽然理论上绝对没有什么可以阻止你创建一个允许你处理然后继续使用该对象的类,但是我想不出一个需要这样做的情况(除了检查是否需要)对象已被处置,例如IsDisposed)。

通常使用的模式是扔掉处置的对象,并在必要时重新创建它们,事实上在许多情况下,尝试访问已处置的对象将导致ObjectDisposedException被抛出。如果您正在创建一个实现IDisposable的对象,那么遵循此约定是个好主意。

为了帮助跟踪哪些对象已被丢弃(以及确保您的对象被丢弃,即使在抛出异常的情况下),请使用using语句:

using (SomeObject o = new SomeObject())
{
    o.DoStuff();
}

答案 3 :(得分:0)

我喜欢在实现IDisposable时使用这种模式...

private bool m_disposed;

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

public void Dispose(bool disposing)
{
    if (!m_disposed)
    {
        if (disposing)
            // Cleanup and close resources

        m_disposed = true;
    }
}

然后在课堂上的所有其他方法中我会这样做......

public void DoMoreStuff()
{
    if (m_disposed)
        throw new ObjectDisposedException();

  // Your code here
}

public void DoStuff()
{
    if (m_disposed)
        throw new ObjectDisposedException();

    // Your code here
 }