Почему это утверждение терпит неудачу?Почему это сравнение цветов не удается?
Assert.AreEqual(Color.Red, Color.FromArgb(Color.Red.A, Color.Red.R, Color.Red.G, Color.Red.B));
Почему это утверждение терпит неудачу?Почему это сравнение цветов не удается?
Assert.AreEqual(Color.Red, Color.FromArgb(Color.Red.A, Color.Red.R, Color.Red.G, Color.Red.B));
Вот как реализовано сравнение Цвета:
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;
}
Как это работает:
value
сравниваться. Это значения Argb текущего экземпляра (они хранятся в одном поле типа long
). Итак, если у Argb разные, у нас разные цвета. Вы успешно пройдете этот шаг.state
по сравнению. Он показывает способ создания цвета: от Argb, от KnownColor или по имени. На самом деле ваше сравнение не выполняется на этом шаге.knownColor
по сравнению. Он имеет значение перечисления KnownColor, или ноль, если цвет не был создан из известного цвета.name
по сравнению. Он имеет значение null
для всех цветов, кроме созданных по имени.Так что, если вы хотите сравнить значения цветов, вы должны использовать value
поле сравнения (он возвращается методом ToArgb):
Assert.AreEqual(color1.ToArgb(), color2.ToArgb());
Редактировать
Чтобы создать копию определенного цвета, вы можете использовать следующий способ расширения:
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());
}
Теперь утверждение проходит:
Assert.AreEqual(Color.Red, Color.Red.Copy());
Но это не имеет никакого смысла, потому что вы можете использовать один экземпляр цвета в любом месте вашей программы :)
Color.Red
именованный цвет, в то время как Color.FromArgb(...)
нет. Поэтому они не считаются равными, хотя они имеют одинаковые значения ARGB. Обратите внимание, что строковое представление также отличается:
Color.Red.ToString() : "Color [Red]"
Color.FromArgb(...).ToString() : "Color [A=255, R=255, G=0, B=0]"
Equals
переопределения Color
проверки класса, будут ли названы оба цвета (известный) цвет или нет:
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(this.name)));
}
}
return false;
}
Поскольку цвет является структурой, он обладает многими свойствами, отличными от значений ARGB. Например, если вы создаете цвет, используя два разных подхода, они будут иметь разные имена; таким образом, они не будут равны.
Color a = Color.Red;
Color b = Color.FromArgb(a.A, a.R, a.G, a.B);
string name1 = a.Name; //name is Red
string name2 = b.Name; //name is ffff0000
Структуры не имеют никакой логики равенства сами по себе (то есть., Если вы хотите использовать «==»). Таким образом, для каждой структуры, этот оператор должен быть определен. Если вы исследуете Color, вы увидите следующее определение оператора '=='. Это зависит от того, как этот оператор реализован.
// Summary:
// Tests whether two specified System.Drawing.Color structures are equivalent.
//
// Parameters:
// left:
// The System.Drawing.Color that is to the left of the equality operator.
//
// right:
// The System.Drawing.Color that is to the right of the equality operator.
//
// Returns:
// true if the two System.Drawing.Color structures are equal; otherwise, false.
public static bool operator ==(Color left, Color right);
Кроме «Равно» является переопределен в структуры таким образом, что он проверяет эквивалентность структур;
// Summary:
// Tests whether the specified object is a System.Drawing.Color structure and
// is equivalent to this System.Drawing.Color structure.
//
// Parameters:
// obj:
// The object to test.
//
// Returns:
// true if obj is a System.Drawing.Color structure equivalent to this System.Drawing.Color
// structure; otherwise, false.
public override bool Equals(object obj);
Неправда. В случае 'Color b = Color.FromArgb (a.A, a.R, a.G, a.B);' name будет 'null'. –
@ lazyberezovsky вы пробовали это? Я пробовал, и он ведет себя так, как говорится в ответе. – daryal
Свойство 'Name' просто генерирует строку, если ее нет. Я указал на это, потому что свойство 'Name' не используется для сравнения. Используется только фактическое поле 'name'. –
Это является следствием реализации структуры System.Drawing.Color
. Он имеет отдельное свойство Name
, которое является «красным» для Color.Red
, но отличается, когда вы создаете свой собственный Color
от Color.Red
. System.Windows.Media.Color
(т.е. реализация WPF Color
) не проявляет этой же проблемы.
это сделать: Color.Red.ToArgb() == Color. FromArgb (255, 0, 0) .ToArgb() – BlueVoodoo
См. Здесь http://stackoverflow.com/questions/7464994/how-to-compare-a-color-by-the-getpixel-method-and-a-color -passed-in-a-method-lik – nawfal