如何处理我们没有参考的一次性物品?

时间:2009-10-08 18:01:29

标签: c# .net idisposable garbage-collection

如果你有一把刷子和笔,如下所示:

Brush b = new SolidBrush(color);
Pen p = new Pen(b);

并像这样处理它们:

b.Dispose();
p.Dispose();

如果是这样的话,你将如何处置它?

Pen p = CreatePenFromColor(color)会为你创造画笔和笔吗?我不能把刷子放在这个方法里面,对吗?

这是一种不能与一次性物品一起使用的方法吗?

编辑:我的意思是,你如何处置BRUSH?

5 个答案:

答案 0 :(得分:9)

CreatePenFromColor方法的工作是处理Brush实例。它一目了然并不明显,但如果你深入研究Pen类的实现,你会发现它不会保留传入的Brush实例。相反,它只是用它来计算一些值。所以没有理由让Brush实例超出对CreatePenFromColor的调用,并且该方法应该处理实例。

答案 1 :(得分:6)

完成后你仍然需要处理它。

例如,您可以这样称呼它:

using (Pen p = CreatePenFromColor(color))
{
    // do something
}

如果方法返回IDisposable对象,则有责任将其丢弃。

[编辑] 现在我得到了一个问题 - 您正在使用Pen(Brush b)构造函数。

一个。在这种情况下,似乎Pen在构造函数之后不需要Brush实例,因此您的方法可能如下所示:

public Pen CreatePenFromColor(Color c)
{
    using (Brush b = new SolidBrush(c))
    { return new Pen(b); }
}

湾为什么不简单地使用Pen(Color color)

public Pen CreatePenFromColor(Color c)
{
    return new Pen(c);
}

℃。 (关于注释)如果Pen在内部持有对Brush的引用,那么在完成Pen之前你将无法处理它。在那种情况下,我会选择一个可以帮我完成工作的课程:

public class PenHelper : IDisposable
{
     private readonly Brush _brush;
     public PenHelper(Color color)
     {
         _brush = new SolidBrush(color);
     }

     public Pen CreatePen()
     {
         return new Pen(_brush);
     }

     public void Dispose()
     {
         _brush.Dispose();
     }
}

然后像这样使用它:

using (PenHelper penHelper = new PenHelper(Color.Black))
{
     using (Pen pen = penHelper.CreatePen())
     {
          // do stuff
     }
}

免责声明:IDisposable不是根据指南实施的,而是仅用于演示。此外,整个示例仅用于说明如何在需要时封装引用。你当然应该选择Pen(颜色)。

答案 2 :(得分:2)

您的问题没有一般解决方案。

在您的具体示例中,这不是问题,因为Pen有一个直接获取Color的构造函数。

有些类会自己处理它们的构造函数参数(特别是与Stream相关的类);检查Reflector中的每个类。

如果您要返回的类继承自Component,则可以为其Disposed事件添加处理程序。

如果您要返回的类没有密封,您可以创建一个继承的版本来处理您创建它的对象。

最后,如果你真的想要,你可以创建一个包含你正在返回的对象的包装类并处理构造函数参数。但是,这将非常令人困惑,我不会推荐它。

答案 3 :(得分:1)

我对许多与图形相关的类的一个问题是,没有一致的模式来处理这些问题。真正需要的是实现部分引用计数的方法。不是在COM样式中,传递引用需要不断地引用引用计数,但是在给定IDisposable图形对象的情况下,可以请求另一个共享相同底层资源的实例。资源本身将封装在具有引用计数器的共享对象中。创建另一个引用实例会增加计数器;在引用实例上调用Dispose会减少它。这样可以避免95%的引用计数开销,同时保留99%的收益。

答案 4 :(得分:0)

当一个方法移交IDisposable实例时,它会同时移交生命周期管理职责。

现在是调用者在使用后处理对象的责任。如果该对象包含其他IDisposable对象,按照惯例,我们必须期望容器在我们处理它时正确处理它的子节点 - 否则它将暗示容器中的错误。

在您的具体示例中,您应该期望Pen在处理它时处置其内部Brush实例。

相关问题