我应该在字体属性的setter中处理旧字体吗?

时间:2016-11-25 15:12:36

标签: c# fonts

我有一个设置对象,用于包含多个字体的报告。

他们是默认的

public Font TitleFont { get; set; } = new Font("Arial", 8, FontStyle.Bold);

但是在用于报告的gdi +渲染之前,它们可以在许多地方进行更改。这不是在winForms控件中。

字体实现IDisposable所以我应该在属性的setter中处理旧字体吗?或者我应该将字体名称,大小和样式存储为3个属性,只在需要时创建字体?

1 个答案:

答案 0 :(得分:0)

这里的主要问题是该类是否对字体负责。 如果是,它应该Dispose字体:

 public class MyFontStorage: IDisposable {
   private Font m_MyFont; 
   ... 
   public Font MyFont {
     get {
       return m_MyFont; 
     } 
     set {
       if (m_MyFont == value)
         return;

       if (m_MyFont != null)
         m_MyFont.Dispose();

       m_MyFont = value;             
     }  
   }

   protected virtual void Dispose(bool disposing) {
     if (disposing) {
       MyFont = null;
     }
   }

   public void Dispose() {
     Dispose(this);

     GC.SuppressFinalize(this); 
   } 
 }

...

 using (MyFontStorage storage = new MyFontStorage()) {
   ...
   // Storage is responsible for the font
   storage.MyFont = new Font(...);
   ...
   // Control has responsibility for the font as well, that's why
   // we have to create a copy in order to each font instance has one owner
   MyControl.Font = new Font(MyFontStorage.MyFont, MyFontStorage.Font.Style);  
   ... 
 }  

创建副本而不仅仅是分配是不良做法(容易出错),这就是为什么你可能想要实现工厂 -

  

"我应该存储字体名称,大小和样式"

 public class MyFontFactory {
   private string m_FamilyName;
   private float m_Size;
   private FontStyle m_Style;

   ...

   public MyFontFactory(Font propotype) {
     ...
     m_FamilyName = propotype.FontFamily.Name;
     m_Size = propotype.Size;
     m_Style = propotype.Style;  
   } 

   public Font CreateFont() {
     return new Font(m_FamilyName, m_Size, m_Style);
   }
 } 

...

 MyFontFactory factory = new factory(SomeControl.Font);
 ...  
 // Much more natural:
 // MyFontFactory creates a new font and MyControl takes responsibility for it
 MyControl.Font = factory.CreateFont(); 

最后,在辅助类/实用程序/例程等的情况下

 public class MyFontMisc {
   private Font m_MyFont;

   public Font MyFont {
     get {
       return m_MyFont; 
     } 
     set {
       m_MyFont = value;             
     }  
   }

   // Just some computations
   public float EmSizeInMillimeters {
     get {
       if (null == m_MyFont)
         return 0.0;

       ...
     }  
   }
 } 

...

 // MyFontMisc doesn't hold any responsibility for the font  
 MyFontMisc misc = new MyFontMisc(SomeControl.Font); 

 // MyFontMisc just uses font for some computation and doesn't take 
 // any responsibility for the font (which owns to SomeControl) 
 Length = misc.EmSizeInMillimeters * 3.0f + 15.0f;