2012-04-03 19 views
9

このアサーションはなぜ失敗しますか?この色の比較が失敗するのはなぜですか?

Assert.AreEqual(Color.Red, Color.FromArgb(Color.Red.A, Color.Red.R, Color.Red.G, Color.Red.B)); 
+4

この操作を行います。:今アサーションは合格Color.Red.ToArgb()==色。 FromArgb(255,0,0).ToArgb() – BlueVoodoo

+0

ここをクリックhttp://stackoverflow.com/questions/7464994/how-to-compare-a-color-by-the-getpixel-method-and-acolor -pass-in-a-method-lik – nawfal

答えて

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

仕組み:

  1. フィールドvalueを比較しました。現在のインスタンスのArgb値です(これらは1つのフィールドlongに格納されています)。したがって、Argbが異なる場合、我々は異なる色を持っています。このステップを正常に渡します。
  2. フィールドstateを比較しました。色がどのように作成されたかを示します:Argbから、KnownColorから、または名前で。 実際には、この手順で比較が失敗します。
  3. フィールドknownColorを比較しました。既知の色から色が作成されなかった場合は、KnownColor列挙型の値を持ちます。
  4. フィールド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()); 

をしかし、あなたはあなたのプログラムのすべての場所で単一色のインスタンスを使用することができますので、それは、意味をなさない:)

2

Color.RedColor.FromArgb(...)はないが、名前の色です。したがって、同じARGB値を持っていても、同じとはみなされません。文字列表現が異なることに注意してください:

Color.Red.ToString()   : "Color [Red]" 
Color.FromArgb(...).ToString() : "Color [A=255, R=255, G=0, B=0]" 
2

ColorクラスチェックのEqualsオーバーライド、両方の色が命名されているかどうか(既知の)色かどうか:

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

カラー構造体であるので、 ARGB値以外の多くのプロパティを持っています。たとえば、2つの異なるアプローチを使用して色を作成する場合、色は異なる名前になります。したがって、彼らは平等ではありません。

 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); 
+0

そうではありません。 'Color b = Color.FromArgb(a.A、a.R、a.G、a.B)の場合、' nameは 'null'になります。 –

+0

@ lazyberezovskyこれを試してみましたか?私は試してみて、それが答えにどのように記述されているのか振る舞います。 – daryal

+0

プロパティ 'Name'は実際には文字列を生成しません。比較のために 'Name'プロパティが使われていないので、私はこれを指摘しました。実際のフィールド 'name'だけが使用されます。 –

2

これは、System.Drawing.Color構造の実装の結果です。別のNameプロパティがあります。Color.Redの場合は "赤"ですが、ColorColor.Redから作成した場合は異なります。 System.Windows.Media.Color(つまり、WPFのColor実装)では、この同じ問題は発生しません。ここで

関連する問題