C#使用语句更加了解

shy*_*am_ 6 c# using

有人可以帮我理解下面的代码

public Font MyFont { get; set; }

void AssignFont()
{
    using (Font f = new Font("Shyam",2))
    {
        this.MyFont = f;
    }
}
Run Code Online (Sandbox Code Playgroud)

将处置对象分配给MyFont属性是否有效?

Mic*_*kyD 9

虽然它可能"有效地将已处置的对象分配给MyFont属性",但该对象可能不再有用,因为它可能已释放托管和/或非托管资源.在using语句开头实例化的对象表明对象的底层类实现了IDisposable接口.这应该被视为一个警告标志,当对象被处置时,你应该真的停止与它交互,包括保持对它的引用.

对于字体,退出using块时会处理字体的底层资源:

using (Font f = new Font("Shyam",2))
{
    this.MyFont = f;
}
Run Code Online (Sandbox Code Playgroud)

如果您尝试在任何绘图操作中使用该字体,则可以很容易地证明这一点.

此代码将失败,System.ArgumentException因为字体被处置:

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
    }

    private void UserControl1_Load(object sender, EventArgs e)
    {
        if (DesignMode)
        {
            return;
        }

        AssignFont();
    }

    #region Overrides of Control

    /// <summary>
    /// Raises the <see cref="E:System.Windows.Forms.Control.Paint"/> event.
    /// </summary>
    /// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs"/> that contains the event data. </param>
    protected override void OnPaint(PaintEventArgs e)
    {
        try
        {
            var g = e.Graphics;

            g.FillRectangle(Brushes.White, e.ClipRectangle);

            g.DrawString("Hi there", MyFont, Brushes.Black, 0, 0); // <--- this will fail
        }
        catch (Exception ex)
        {
            Trace.TraceError(ex.Message);
        }
    }

    #endregion

    void AssignFont()
    {
        using (Font f = new Font("Shyam", 2))
        {
            this.MyFont = f;
        } // <---- MyFont now points to a disposed object
    }

    public Font MyFont { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

您的代码的问题在于您正在使用块中分配某些内容并在其他位置保留对它的引用.在您的场景中,因为您想在其他地方使用该字体,所以有一个using块是没有意义的.

坏:

using (Font f = new Font("Shyam",2))
{
    this.MyFont = f;
}
Run Code Online (Sandbox Code Playgroud)

更好:

this.MyFont = new Font("Shyam",2)
Run Code Online (Sandbox Code Playgroud)

我怀疑的字体使用原生字体,因此是资源.