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?
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; }
}
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.
using (Font f = new Font("Shyam",2))
{
this.MyFont = f;
}
this.MyFont = new Font("Shyam",2)
Fonts I suspect make use of native fonts hence the resource.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With