Title: Use value equality to compare font objects in C#
This example explains the difference between reference equality and value equality, and shows how you can test value equality for font objects.
Reference equality asks whether two variables refer to the same object. In contrast, value equality asks whether two objects have the same values.
For example, a program could create two different Font objects that have the same property values for Name, Size, Style, and so forth. The variables pointing to those objects would have value equality because they refer to objects with the same values, but they would not have reference equality because they wouldn't refer to a single Font instance.
Many classes provide only reference equality (because it's easier). Unfortunately you often need to know whether two objects represent the same logical thing, not whether they happen to refer to the same instance.
The example Display a font selection dialog with an Apply button in C# uses the following code to display its font selection dialog.
// Display the dialog.
private void btnSelectFont_Click(object sender, EventArgs e)
{
// Save the original font.
Font original_font = this.Font;
// Initialize the dialog.
fdFont.Font = this.Font;
// Display the dialog and check the result.
if (fdFont.ShowDialog() == DialogResult.OK)
{
// Apply the selected font.
this.Font = fdFont.Font;
}
else
{
// Restore the original font.
this.Font = original_font;
}
}
In that example, setting the form's font is quick and easy. If your application needs to do a lot of work (for example, creating a complex drawing that uses the font), you can save time by checking the form's current font to see if it needs to be changed. For example, if the user clicked Apply and then OK so the dialog is still selecting the font that the form is already showing, then you don't need to set the form's font again.
Unfortunately the Font class's Equals method and == test for reference equality, so it only returns true if two Font variables refer to the same object instance. That doesn't do much good in this example (or really most examples I can think of) because the font dialog has its own Font object to represent its font.
This example uses the following Font extension method to test two Font objects for value equality.
public static class FontExtensions
{
// Return true if the Fonts represent the same font.
// Note that the FontStyle property includes
// Bold, Italic, Regular, Strikeout, and Underline.
public static bool ValueEquals(this Font font, Font other)
{
if (font.Name != other.Name) return false;
if (font.SizeInPoints != other.SizeInPoints) return false;
if (font.Style != other.Style) return false;
return true;
}
}
The ValueEquals method compares the Font objects' names, sizes, and styles. If any of those properties is different, the method returns false to indicate that the fonts are different. If all of the properties are the same, the method returns true.
This example's main program uses the ValueEquals method in the following revised code.
// Display the dialog.
private void btnSelectFont_Click(object sender, EventArgs e)
{
// Save the original font.
Font original_font = this.Font;
// Initialize the dialog.
fdFont.Font = this.Font;
// Display the dialog and check the result.
if (fdFont.ShowDialog() == DialogResult.OK)
{
// Apply the selected font.
if (!this.Font.ValueEquals(fdFont.Font))
this.Font = fdFont.Font;
}
else
{
// Restore the original font.
if (!this.Font.ValueEquals(original_font))
this.Font = original_font;
}
}
Now if the form's font already has the correct value, the code doesn't set it again.
The ValueEquals method may save a tiny bit of time in this example, but the more important lesson to be taken from this example is the difference between reference and value equality.
Download the example to experiment with it and to see additional details.
|