System.Drawing.Color相等运算符不会将0xffffffff视为Color.White

时间:2011-11-16 03:49:36

标签: .net colors system.drawing system.drawing.color

为什么评估为false

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

更新这是设计的。

以下是Equals结构中反编译Color函数的副本:

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;
}

我的问题是,为什么MSFT会让我将这种丑陋的方式比作白色?!?!?

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;
}

另外,我不明白为什么FromArgbColor函数的1-arg重载需要int,它应该能够取{{1} (uint

7 个答案:

答案 0 :(得分:6)

这只是how colors in .NET work

  

此结构仅与其他Color结构进行比较。至   只根据他们的ARGB值比较颜色,你应该这样做   以下内容:

     

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

     

这是因为.Equals和==运算符确定等价   使用的不仅仅是颜色的ARGB值。例如,   Color.Black和Color.FromArgb(0,0,0)自认为不相同   Color.Black是一个命名颜色,Color.FromArgb(0,0,0)不是。

修改:其他答案。

  

我的问题是,为什么MSFT会让我将这种丑陋的方式比作白色?!?!?

如果您要以这样的方式比较颜色,以便知道它们是否与ARGB组件的值完全相同,那么在“丑陋”的方式。如果您像大多数.NET程序员使用Color结构一样比较颜色,那么您只想知道某些颜色是White还是Red还是{{1和“漂亮”的方式(使用Equals和==)简单易用,易读。

此外,“丑陋”的方式不是你发布的方法,就是这样:

Chartreuse

这不是那么难看。

  

另外,另外一件事我不明白为什么Color的1-arg构造函数需要一个int,它应该能够取一个uint(0xffffffff)

我会说能够接受if (color1.ToArgb() == color2.ToArgb()) ... ,这要归功于不可避免的混乱和颜色错误。编写方法可以很容易地做到这一点。

答案 1 :(得分:1)

颜色是一种结构,它包含多于四个字节的值。 试试这个:

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

答案 2 :(得分:1)

Color.FromArgb(255,255,255,255)不是命名颜色,因此其Name属性为ffffff,对于命名颜色,Color.White Name将为White。所以你的比较不会起作用

您可以使用

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

(Color.FromArgb(255, 255, 255, 255).R == Color.White.R && Color.FromArgb(255, 255, 255, 255).G == Color.White.G && Color.FromArgb(255, 255, 255, 255).B == Color.White.B && Color.FromArgb(255, 255, 255, 255).A == Color.White.A)

答案 3 :(得分:0)

如果我必须使用HTML颜色(我更喜欢),我使用这个: TextBox1.BackColor = System.Drawing.ColorTranslator.FromHtml(“#FFFFFF”)

答案 4 :(得分:0)

名称不同,请在立即窗口中查看以下结果:

?Color.FromArgb(255, 255, 255, 255)
"{Name=ffffffff, ARGB=(255, 255, 255, 255)}"
    A: 255
    B: 255
    G: 255
    IsEmpty: false
    IsKnownColor: false
    IsNamedColor: false
    IsSystemColor: false
    Name: "ffffffff"
    R: 255

?Color.White
"{Name=White, ARGB=(255, 255, 255, 255)}"
    A: 255
    B: 255
    G: 255
    IsEmpty: false
    IsKnownColor: true
    IsNamedColor: true
    IsSystemColor: false
    Name: "White"
    R: 255

答案 5 :(得分:0)

我花了30分钟研究这个原因你也让我对此感到好奇,但是当我回来时,看起来像其他人发布了我发现的确切内容。 你在比较两件不同的事情。您必须将它们放在同一级别,以便您可以比较它们,无论是使用system.drawing属性还是其他一个海报建议。

答案 6 :(得分:0)

public static class ExtendsUInt32
    {
        /// <summary>
        /// Converts a System.UInt32 to a System.Drawing.Color.
        /// Ex: var orangyColor = (0xFFDDAA22).ToColor(); //some kind of orange
        /// <remarks>
        /// Easier than writing var orangyColor = Color.FromArgb(unchecked((int)0xFFDDAA22))),
        /// or var orangyColor = Color.FromArgb(255,230,200,50);
        /// </remarks>
        /// </summary>
        /// <param name="color">A uint containing bytes A,R,G,B in high-to-low order (whatever this stores as on your platform's endianness).</param>
        /// <returns>A freshly picked System.Drawing.Color.</returns>
        public static Color ToColor(this UInt32 color)
        {
            var bytes = BitConverter.GetBytes(color);
            if (BitConverter.IsLittleEndian) { bytes = bytes.Reverse().ToArray(); }
            return Color.FromArgb(bytes[0],bytes[1],bytes[2],bytes[3]);
        }
    }