Search code examples
c#using

C# using statement more understanding


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?


Solution

  • 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.