ProfileWell, I thought it was i...PhotosBlogListsMore ![]() | Help |
|
September 29 Two colors redIf you take a quick look here you’ll have read an interesting article about “well known values” of common types. One example Abhinaba gives is Color.Red and new Color(255,0,0), which he says are “the same”. Moving swiftly over the fact that he meant Color.Red and Color.FromArgb(255,0,0), what about that equivalence claim? Well, I suppose it depends how you define equivalence. If you use either of those colors to construct a SolidBrush and paint a nice big rectangle on the screen, then they’ll both look the same. So, in that sense they are “the same”. But try running this little console application, and examine the output. using System; using System.Collections.Generic; using System.Text; using System.Drawing;
namespace TwoColorsRed { class Program { static void Main(string[] args) { Color red1 = Color.Red; Color red2 = Color.FromArgb(255, 0, 0); //Color red2 = Color.FromName("Red");
if (red1 == red2 ) { Console.WriteLine( String.Format("Red1({0},{1},{2},{3}) and Red2({4},{5},{6},{7}) " + "are the same...the Universe is safe", red1.A, red1.R, red1.G, red1.B, red2.A, red2.R, red2.G, red2.B) ); } else { Console.WriteLine( String.Format("Red1({0},{1},{2},{3}) and Red2({4},{5},{6},{7}) " + "are not the same...call the ChromaCops", red1.A, red1.R, red1.G, red1.B, red2.A, red2.R, red2.G, red2.B) ); } Console.ReadKey(); } } } Delve into Color.Equals() or Color.op_Equality() (operator ==) and you’ll find that things are not quite so simple. In fact, both of these methods of determining equivalence also check other properties. First, there’s the state of the color. Did you know that not all colors are actually useful? If we pass an unknown name to Color.FromName(), then you still get a Color object back – it just isn’t valid. Then, it checks whether the colors in question are well-known or not, and also compares by Name (which is a read-only property, so you have no real control over this). So, when it comes to our first example Color.Red is a known color, but Color.FromArgb(255,0,0) is not; and anyway, their names don’t match either. So, why would I care? Red is red, isn’t it? Well – there are often good reasons for trying to compare two colors – trying to find a match in a fixed palette, or looking for similar pixels in a bitmap region, for example. You need to check the (A)RGB values by hand, rather than using the seemingly-handy comparison functions. This is a more general issue, both for API designers and consumers. From the API designer’s point of view it is recommended that, if you are providing equality overrides, that your comparator should perform an identity-like compare. The Color.Red and your Color.FromArgb(255,0,0) are clearly not the same color, in an identity sense – they’ve got different names for a start! However, from a consumer’s point of view, you often don’t want an “identity” comparison – especially with value types. More often than not, you need a semantic comparison appropriate to your application (like comparing the color values). And you have to write that yourself. If it is a very common comparison to perform, then you might be tempted to ask the API designer to roll it into the class concerned (especially if you are the API designer, too), but you should be very careful before deciding to do so. You don’t want to confuse the situation further by adding an army of subtly different comparison functions to a simple class or struct – especially one like Color. Tricky fellow, equality. Comments (6)
Trackbacks (4)The trackback URL for this entry is: http://mwadams.spaces.live.com/blog/cns!652A0FB566F633D5!1832.trak Weblogs that reference this entry
|
|
|