为什么这个断言失败了?
Assert.AreEqual( Color.Red, Color.FromArgb( Color.Red.A, Color.Red.R, Color.Red.G, Color.Red.B ) );
答案 0 :(得分:11)
以下是颜色比较的实现方式:
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());
但这没有任何意义,因为您可以在程序的每个位置使用单色实例:)
答案 1 :(得分:2)
Color.Red
是一种命名颜色,而Color.FromArgb(...)
则不是。Color.Red.ToString() : "Color [Red]"
Color.FromArgb(...).ToString() : "Color [A=255, R=255, G=0, B=0]"
。因此,即使它们具有相同的ARGB值,它们也不被认为是平等的。请注意,字符串表示也不同:
{{1}}
答案 2 :(得分:2)
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;
}
答案 3 :(得分:2)
由于Color是一个结构,它具有除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);
在结构中也覆盖'Equals',以便检查结构的等价性;
// 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);
答案 4 :(得分:2)
这是System.Drawing.Color
结构实现方式的结果。它有一个单独的Name
属性,Color.Red
为“红色”属性,但是当您从Color
创建自己的Color.Red
时,属性会有所不同。 System.Windows.Media.Color
(即WPF的Color
实施)没有出现同样的问题。