C# - 与设计相关的处理问题(拿两个)

时间:2010-01-06 18:35:24

标签: c# fonts dispose encapsulation

我今天早些时候提出了一个问题,但我认为我需要以不同的方式处理它(最重要的是有关于DataSet的“挂断”)。

这是一个封装了Font的创建的类(换句话说,它是从xml文件中读取数据,并在运行时根据从该文件中读取的内容创建字体):

public class FontCreator
{
    private Font m_TheFont = null;

    public FontCreator( ... some parameters ... )
    {
        m_TheFont = GetTheFont();
    }

    public Font TheFont
    {
        return m_TheFont;
    }

    private Font GetTheFont()
    {
        // code, and more code, that eventually leads to:

        Font f = new Font(fntFamily, fntSize, fntStyle);
        return f;
    }
}

FontCreator类的使用者看起来像:

public class TheConsumer()
{
    private FontCreator m_FontCreator = null;

    public TheConsumer()
    {
        m_FontCreator = new m_FontCreator( ... some parameters ... );
        Initialize();
    }

    private void Initialize()
    {
        InitializeThis();
        InitializeThat();
    }

    private void InitializeThis()
    {
        .... some code ...
        SomeObject.ApplyFont(m_FontCreator.TheFont);
    }

    private void InitializeThat()
    {
        ... some code ...
        SomeObject.ApplyFont(m_FontCreator.TheFont);
    }
}

您添加了哪些代码,以及确保明确调用“TheFont”的Dispose方法的位置?

4 个答案:

答案 0 :(得分:3)

public TheConsumer()
{
    using (m_FontCreator = new m_FontCreator( ... some parameters ... ))
    {
        Initialize();
    }
}

答案 1 :(得分:3)

如果您不希望在最初使用后保留对TheFont的引用,请在Initialize之后立即在构造函数中调用它的Dispose方法。如果你希望TheConsumer保持活力一段时间并保持对TheFont的引用,它会变得更有趣。两个选项:

  1. 您可以从TheConsumer对象的析构函数中调用TheFont的dispose方法。这不是常见做法,也存在问题。主要是,直到垃圾收集发生才会调用此方法。更好的是:
  2. 您可以使TheConsumer对象本身实现IDisposable,并从TheConsumer.Dispose调用TheFont.Dispose。由于TheConsumer实现了IDisposable,使用 it 的代码应该调用它的Dispose方法。
  3. 编辑以回应严厉的评论! 是的,如果有的话,我应该明确只使用1 2。我知道所有开发人员都在假设注意到IDisposable实现时,但他们通常不这样做。如果引用的受管资源可能确实存在很长时间并且如果处理不当会导致问题,我有时会在持有引用的对象的析构函数中调用安全的Dispose()方法。那是错的吗? :)

答案 2 :(得分:3)

我很困惑,如果你想快速使用字体创建器对象,那么在IDisposable上实现FontCreater并使用

using(m_FontCreator = new FontCreater(....))
{
   InitializeThis();
   InitializeThat();
}

如果您需要在FontCreater的生命周期内保留TheConsumer的实例,请在 IDisposable和{{}}上实施FontCreater {1}}课程。

TheConsumer

然后像这样使用public class TheConsumer : IDisposable { void Dispose() { if(m_FontCreator != null) m_FontCreator.Dispose(); } }

TheConsumer

答案 3 :(得分:1)

答案1:避免它。不要将包含非托管资源的对象保留在不必要的时间。

答案2:如果确实需要代码中显示的嵌入字段,则FontCreator和Consumer类都需要实现IDisposable。但不是析构函数(Finalizer) 对此的主要论点是FontCreator是Font的“所有者”,因此应该承担责任。消费者也以同样的方式对造物主负责。

正如其他人所说,似乎你至少可以避免使用Consumer类中的m_FontCreator字段。但这取决于代码的其余部分,m_FontCreator是否在其他地方使用过?