Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.Drawing.Color equality operator doesn't treat 0xffffffff as Color.White

Why does this evaluate to false?

Color.FromArgb(255, 255, 255, 255) == Color.White

Update It's by design.

Here's a copy from the decompiled Equals function in the Color structure:

public override bool Equals(object obj)
{
    //probably failure to convert from C++ source,
    //the following line should be invalid in C#, nevermind
    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(this.name)));
        }
    }
    return false;
}

My question is why on earth would MSFT have me comparing to white the ugly way?!?!?

static bool AreEqual(Color a, Color b)
{
  if (!a.Equals(b))
  {
    return
      a.A == b.A &&
      a.R == b.R &&
      a.G == b.G &&
      a.B == b.B;    
  }
  return true;
}

Also, another thing I don't get why the 1-arg overload of the FromArgb function in Color takes an int, it should be able to take a uint (0xffffffff)

like image 504
Shimmy Weitzhandler Avatar asked Nov 16 '11 03:11

Shimmy Weitzhandler


1 Answers

This is just how colors in .NET work:

This structure only does comparisons with other Color structures. To compare colors based solely on their ARGB values, you should do the following:

if ( color1.ToArgb() == color2.ToArgb()) ...

This is because the .Equals and == operators determine equivalency using more than just the ARGB value of the colors. For example, Color.Black and Color.FromArgb(0,0,0) are not considered equal since Color.Black is a named color and Color.FromArgb(0,0,0) is not.

Edit: additional answers.

My question is why on earth would MSFT have me comparing to white the ugly way?!?!?

If you're comparing colors in such a way that you want to know whether they're exactly the same color down to the values of the ARGB components, then you should be comparing them in the "ugly" way. If you're comparing the colors in the same way that most .NET programmers use the Color structure, then you only want to know if some color is White or Red or Chartreuse, and the "pretty" way (using Equals and ==) is simple, easy to use, and very readable.

Also, the "ugly" way isn't the method you posted, it's this:

if (color1.ToArgb() == color2.ToArgb()) ...

which isn't really that ugly.

Also, another thing I don't get why the 1-arg constructor of Color takes an int, it should be able to take a uint (0xffffffff)

I would say it should not be able to take a uint, thanks to the inevitable confusion and color errors that would cause. It's easy to write a method to do this.

like image 64
MusiGenesis Avatar answered Dec 01 '22 03:12

MusiGenesis