简体   繁体   English

在C#中布置字体对象

[英]Disposing Font Object in C#

I have the following code 我有以下代码

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();

When I run the code analysis, it shows an error that 'font' is not disposed along all exception paths. 当我运行代码分析时,它显示出一个错误,即“字体”未沿所有异常路径放置。 What's the proper way to dispose it in the above code? 在上面的代码中处理它的正确方法是什么?

Thanks. 谢谢。

You should not Dispose ComboBox.Font : it should do ComboBox itself . 不应该处理 ComboBox.Font :它应该做ComboBox 本身 You can create a Font copy instead: 您可以创建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);
}

The clue is in the phrase "all exception paths". 线索在短语“所有异常路径”中。 Essentially, Code analysis has noticed that an exception could be thrown by the DrawString calls, and that the Dispose would not be called in that case. 从本质上讲,代码分析已经注意到DrawString调用可能引发异常,并且在这种情况下不会调用Dispose

There is also the question of disposing an object which you did not create, so a simple flag would suffice there. 还有一个问题是要处置一个您没有创建的对象,因此在那里有一个简单的标志就足够了。

As Samuel noted in the comments, wrap the block in a try...finally and call Dispose in the finally block, like this: 正如Samuel在评论中指出的那样,将块包装在try...finally Dispose中,然后在finally块中调用Dispose ,如下所示:

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();
}

Code Analysis will still complain at this, as the Dispose is conditional on the value of created , and the code analysis tool is not sophisticated enough to be able to determine that the creation and disposal conditions are identical. 由于Dispose取决于created的值,并且代码分析工具不够复杂,无法确定创建条件和处置条件是否相同,因此Code Analysis仍然会抱怨。 The solution to that is shown in Dmitry's answer , specifically to create a new Font whatever the value of condition1 , and to use that condition instead to choose the appropriate value within the font object. Dmitry的答案显示了该解决方案,特别是无论condition1的值如何,都创建一个新Font ,并使用该条件在font对象中选择适当的值。

You problem is to only dispose the font if you have to create a new one. 您的问题是仅在必须创建新字体时才处理字体。 So this is the code you need to use: 这是您需要使用的代码:

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);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM