Why does this assertion fail?
Assert.AreEqual( Color.Red, Color.FromArgb( Color.Red.A, Color.Red.R, Color.Red.G, Color.Red.B ) );
The most common method would be a visual color comparison by looking at two physical color samples side by side under a light source. Color is very relative, so you can compare colors in terms of the other color across dimensions such as hue, lightness and saturation (brightness).
In order to measure the difference between two colors, the difference is assigned to a distance within the color space. In an equidistant-method color space, the color difference ∆E can be determined from the distance between the color places: ΔE = √ (L*₁-L*₂)² + (a*₁-a*₂)² + (b*₁-b*₂)².
Metamerism occurs when two colors match under one type of lighting but not another. This peculiarity has to do with the relationship between light and color. We perceive color based on the way an object reflects light, and that perception is based on the light source.
Here is how Colors comparison implemented:
public override bool Equals(object obj)
{
if (obj is Color)
{
Color color = (Color) obj;
if ((this.value == color.value)
&& (this.state == color.state)
&& (this.knownColor == color.knownColor))
{
return ((this.name == color.name)
|| ((this.name != null)
&& (color.name != null)
&& this.name.Equals(color.name)));
}
}
return false;
}
How it works:
value
compared. It is Argb values of current instance (they are stored in one field of type long
). So, if Argb different, we have different colors. You pass this step successfully.state
compared. It shows the way how color was created: from Argb, from KnownColor, or by name. Actually your comparison fails on this step.
knownColor
compared. It has value of KnownColor enum, or zero, if color was not created from known color.name
compared. It has null
value for all colors except ones created by name.So, if you want to compare values of colors, you should use value
field in comparison (it is returned by ToArgb method):
Assert.AreEqual(color1.ToArgb(), color2.ToArgb());
Edit
To create copy of some color you can use following extension method:
public static class ColorHelper
{
public static Color Copy(this Color color)
{
if (color.IsKnownColor)
return Color.FromKnownColor(color.ToKnownColor());
if (color.IsNamedColor)
return Color.FromName(color.Name);
// this is better, then pass A,r,g,b separately
return Color.FromArgb(color.ToArgb());
}
Now assertion passes:
Assert.AreEqual(Color.Red, Color.Red.Copy());
But it makes no sense, because you can use single color instance in every place of your program :)
Color.Red
is a named color, while Color.FromArgb(...)
is not. So they're not considered equal, even though they have the same ARGB values. Note that the string representation is also different:
Color.Red.ToString() : "Color [Red]"
Color.FromArgb(...).ToString() : "Color [A=255, R=255, G=0, B=0]"
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