5

Can someone help me to understand following code

public Font MyFont { get; set; }

void AssignFont()
{
    using (Font f = new Font("Shyam",2))
    {
        this.MyFont = f;
    }
}

Is it valid to assign a disposing object to MyFont property?

6
  • I have seen this work! Always wanted an explanation though. Commented Nov 19, 2014 at 5:28
  • 1
    How is the MyFont property actually used? Disposing an object which is still referenced is not only fine, it's the normal situation. If you didn't still have a reference to it, you wouldn't be able to dispose it! So, what specifically occurs after this code executes that you think shouldn't work but which does? Commented Nov 19, 2014 at 5:35
  • thanks. I understood now..i should be calling Dispose on MyFont after it has been used. I will be disposing this property in Dispose method of my control. here is explanation from microsoft msdn.microsoft.com/en-us/library/… Commented Nov 19, 2014 at 5:37
  • 1
    Ideally, we should not be having references to a disposed objects to allow GC to collect them. So is this usage of using wrong? Commented Nov 19, 2014 at 5:40
  • @bit: there's nothing wrong per se with retaining a reference to a disposed object. You should eliminate references to objects you won't use again, but this has nothing directly to do with whether the object implements IDisposable, nor whether the object has been disposed, except to the extent that usually when you dispose an IDisposable object, that signals your intent that you are done using the object. What the OP is actually asking here, is not clear at all. Based on the most recent comment, it sounds like they are just not sure of when to dispose an object. Commented Nov 19, 2014 at 5:43

2 Answers 2

10

Whilst it may be "valid to assign a disposed object to MyFont property", the object may no longer be useful because it may have released managed and/or unmanaged resources. Objects that are instantiated in the opening of a using statement indicate that the object's underlying class realises the IDisposable interface. This should be treated as a warning sign that when the object is disposed you should really stop interacting with it including keeping a reference to it.

In the case of a font, the font's underlying resources were disposed when you exited the using block:

using (Font f = new Font("Shyam",2))
{
    this.MyFont = f;
}

This is easily proven if you attempt to use the font in any drawing operation.

This code will fail with a System.ArgumentException because the font is disposed:

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

enter image description here

The problem with your code is that you are allocating something in a using block and keeping a reference to it elsewhere. In your scenario because you want to use the font elsewhere it makes no sense to have a using block.

Bad:

using (Font f = new Font("Shyam",2))
{
    this.MyFont = f;
}

Better:

this.MyFont = new Font("Shyam",2)

Fonts I suspect make use of native fonts hence the resource.

Sign up to request clarification or add additional context in comments.

Comments

4

General rule of thumb: Don't use a disposable object outside the using block. Most of the time, disposable objects are unusable once disposed. If you follow this rule, you'll run into less trouble.

In this specific case, I wouldn't recommend using since you expect to use the font object outside the AssignFont method.

So, when do you dispose the font? One way is, you could dispose the font on the Disposed event of the parent control (assuming this is a control). However, unless you have thousands of fonts being generated during your application lifetime, you most like don't have to dispose the font at all. If you just have 5-10 fonts in the app, disposing them shouldn't be a big point of concern.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.