在C#中处理字体对象

时间:2014-06-05 06:54:44

标签: c# winforms dispose

我有以下代码

Font font = ComboBox.Font;
if(condition1)
font = new Font(font, FontStyle.Bold);
if(condition2)
  e.Graphics.DrawString("One", font, color, rectangle);
else
  e.Graphics.DrawString("Two", font, color, rectangle);
font.Dispose();

当我运行代码分析时,它显示错误“#font;'并未沿所有异常路径放置。在上面的代码中处理它的正确方法是什么?

感谢。

3 个答案:

答案 0 :(得分:3)

不应弃置 ComboBox.Font:它应该ComboBox 本身。 您可以改为创建Font 副本

using (Font font = new Font(ComboBox.Font, condition1 ? FontStyle.Bold : ComboBox.Font.Style)) {
  if (condition2)
    e.Graphics.DrawString("One", font, color, rectangle);
  else
    e.Graphics.DrawString("Two", font, color, rectangle);
}

答案 1 :(得分:2)

线索在短语"所有异常路径"中。从本质上讲,代码分析已经注意到DrawString调用可能会抛出异常,并且在这种情况下不会调用Dispose

还有一个处理你没有创建的对象的问题,所以一个简单的标志就足够了。

正如Samuel在评论中指出的那样,将块包裹在try...finally中并在Dispose块中调用finally,如下所示:

Font font = ComboBox.Font;
bool created = false;

try
{
    if(condition1)
    {
        font = new Font(font, FontStyle.Bold);
        created = true;
    }
    if(condition2)
        e.Graphics.DrawString("One", font, color, rectangle);
    else
        e.Graphics.DrawString("Two", font, color, rectangle);
}
finally
{
    if (created)
        font.Dispose();
}

代码分析仍然会抱怨,因为Dispose取决于created的值,并且代码分析工具不够复杂,无法确定创建和处理条件是相同的。其解决方案显示在Dmitry's answer中,特别是创建一个新的Font,无论condition1的值是什么,并使用该条件来选择字体对象中的适当值。 / p>

答案 2 :(得分:1)

问题是如果必须创建一个新字体,则只处理该字体。所以这是您需要使用的代码:

Action<Font> drawString =
    f => e.Graphics.DrawString(condition2 ? "One" : "Two", f, color, rectangle);

if (condition1)
    drawString(ComboBox.Font);
else
    using (var font = new Font(ComboBox.Font, FontStyle.Bold))
    {
        drawString(font);
    }