Оператор равенства System.Drawing.Color не обрабатывает 0xffffffff как Color.White - PullRequest
5 голосов
/ 16 ноября 2011

Почему это оценивается как 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;
}

Кроме того, я еще не понялНе понимаю, почему 1-аргументная перегрузка функции FromArgb в Color занимает int, она должна иметь возможность uint (0xffffffff)

Ответы [ 7 ]

6 голосов
/ 16 ноября 2011

Это просто , как работают цвета в .NET :

Эта структура сравнивает только другие структуры Color.Чтобы сравнивать цвета, основываясь исключительно на их значениях ARGB, вы должны сделать следующее:

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

Thisпотому что операторы .Equals и == определяют эквивалентность, используя не только значение ARGB цветов .Например, Color.Black и Color.FromArgb (0,0,0) не считаются равными, поскольку Color.Black является именованным цветом, а Color.FromArgb (0,0,0) - нет.

Редактировать : дополнительные ответы.

Мой вопрос, почему на земле MSFT заставил бы меня сравнивать белый с безобразным образом?!?!?

Если вы сравниваете цвета таким образом, что хотите узнать, совпадают ли они по цвету со значениями компонентов ARGB, то вы должны сравнивать их в "уродливом"" путь.Если вы сравниваете цвета так же, как большинство программистов .NET используют структуру Color, то вам нужно знать, является ли какой-то цвет White или Red или Chartreuse, и "красивым"способ (с использованием Equals и ==) является простым, легким в использовании и очень читабельным.

Кроме того, «уродливый» способ - это не метод, который вы опубликовали, а вот такой:

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

что на самом деле не так страшно.

Кроме того, еще одна вещь, которую я не понимаю, почему 1-аргументный конструктор Color принимает целое число, он должен иметь возможность взять uint (0xffffffff)

Я бы сказал, что , а не должно быть в состоянии взять uint, из-за неизбежной путаницы и цветовых ошибок, которые могут вызвать.Для этого легко написать метод.

1 голос
/ 16 ноября 2011

Color.FromArgb (255, 255, 255, 255) не является именованным цветом, поэтому его свойство Name будет ffffff, а для именованного цвета Color.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)
1 голос
/ 16 ноября 2011

Цвет - это структура, которая содержит более четырех байтовых значений. Попробуйте это:

Color.FromArgb(255, 255, 255, 255).ToArgb() == Color.White.ToArgb()
0 голосов
/ 21 июля 2012
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]);
        }
    }
0 голосов
/ 16 ноября 2011

Я потратил 30 минут на изучение этой причины, потому что вы тоже заинтересовались ею, но когда я вернулся, похоже, что другие отправили именно то, что я нашел.Вы сравниваете две разные вещи.Вы должны поместить их на один и тот же уровень, чтобы затем сравнить их, будь то с помощью одного из свойств system.drawing или одного из предложений других авторов.

0 голосов
/ 16 ноября 2011

Имя отличается, см. Эти результаты в окне Immediate:

?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
0 голосов
/ 16 ноября 2011

Если мне нужно использовать цвет HTML (который я предпочитаю), я использую это: TextBox1.BackColor = System.Drawing.ColorTranslator.FromHtml ("# FFFFFF")

...