2011-01-04 7 views
5

私はただ単純に比較すなわちオブジェクトを比較しますか?

byte[] keya = System.Text.Encoding.ASCII.GetBytes("myFamilyColumn:1"); 
byte[] keyb = System.Text.Encoding.ASCII.GetBytes("myFamilyColumn:1"); 
Console.WriteLine(keya == keyb); 

をしなければならないが、結果はfalseで、そのハッシュコードは、私がここで何かが欠けています、また違うのですか?

ありがとうございます!

+2

LINQを使用できる場合は、 'keya.SequenceEqual(keyb)'を実行できます。 – Ani

+0

残念ながら、それはモノラルでは利用できません。 – Ali

+1

これは[2つの.Net配列オブジェクト(バイト配列)の比較](http://stackoverflow.com/q/486749/15639)の複製ではありませんか? – MarkJ

答えて

11

私はフレームワークに配列の平等を与える方法はないと思います。しかし、配列のためにIEqualityComparer<T>の独自の実装を書くのは難しくありません。例えば、(コンパイルされたが未テスト):

public static class ArrayEqualityComparer 
{ 
    public static IEqualityComparer<T[]> Create<T>(
     IEqualityComparer<T> comparer) 
    { 
     return new ArrayEqualityComparer<T>(comparer); 
    } 
} 

public sealed class ArrayEqualityComparer<T> : IEqualityComparer<T[]> 
{ 
    private static readonly IEqualityComparer<T[]> defaultInstance = new 
     ArrayEqualityComparer<T>(); 

    public static IEqualityComparer<T[]> Default 
    { 
     get { return defaultInstance; } 
    } 

    private readonly IEqualityComparer<T> elementComparer; 

    public ArrayEqualityComparer() : this(EqualityComparer<T>.Default) 
    { 
    } 

    public ArrayEqualityComparer(IEqualityComparer<T> elementComparer) 
    { 
     this.elementComparer = elementComparer;   
    } 

    public bool Equals(T[] x, T[] y) 
    { 
     if (x == y) 
     { 
      return true; 
     } 
     if (x == null || y == null) 
     { 
      return false; 
     } 
     if (x.Length != y.Length) 
     { 
      return false; 
     } 
     for (int i = 0; i < x.Length; i++) 
     { 
      if (!elementComparer.Equals(x[i], y[i])) 
      { 
       return false; 
      } 
     } 
     return true; 
    } 

    public int GetHashCode(T[] array) 
    { 
     if (array == null) 
     { 
      return 0; 
     } 
     int hash = 23; 
     foreach (T item in array) 
     { 
      hash = hash * 31 + elementComparer.GetHashCode(item); 
     } 
     return hash; 
    } 
} 

(これは現在elementComparerGetHashCodeEqualsの両方にnull値に対処することを前提としていますインターフェースがそれを保証するものではありませんが、既定の等する比較器は、実際にを行います。 。。あなたはもちろん...私はちょうど今の時間を持っていない、より堅牢に上記のコードを修正することができ、それを扱う)

使用法:

IEqualityComparer<byte[]> x = ArrayEqualityComparer<byte>.Default; 
bool equal = x.Equals(bytes1, bytes2); 

IEqualityComparer<string[]> y = 
    ArrayEqualityComparer.Create(StringComparer.OrdinalIgnoreCase); 
bool whatever = x.Equals(new[][] { "X", "Y" }, new[] { "x", "y" }); 
+0

@ジョン私は、System.Text.Encoding.ASCII.GetBytesの使用についてコメントしていないことに本当に驚いています。 –

+1

@Conrad:これは、OPが2つの "等しい "バイト配列である。 –

+0

@Jon ok that is fair –

4

keyaおよびkeybは、まったく同じバイトを含む2つの全く別個のオブジェクトです。

2つの文字列が同じ文字を持っているかどうかを比較したい場合は、String.Equalsのようなメソッドを調べるべきでしょうか?

+2

はい、または配列を繰り返し、各バイトのペアを比較します。 –

+0

実際には、私はすでにキーを知っているので、バイトの文字列からバイトを取得するので、私はそのキーに対応するオブジェクトを返さなかったが、私は使用するときに、バイト[]データ型のキーのコレクションを反復したくない反復からのキーの参照は、オブジェクトを見つけた、なぜそうですか? – Ali

+0

@Ali:これらのバイト配列をコレクションのキーとして使用しているようですね。まず、これらが文字列の表現であれば、文字列そのものをキーとして使用する方がよいでしょう。そうでない場合は、独自の等価比較関数を記述して、デフォルトの代わりにそれを使用するようにコレクションに指示できます。 –

1

この一般的な拡張機能は、トリックを行う必要があります。

public static class ArrayExtensions 
{ 
    public static bool ElementsEqual<T>(this T[] left, T[] right) 
     where T : IEquatable<T> 
    { 
     if (left == null || right == null) 
     { 
      return !(left == null^right == null); 
     } 
     else if (left.Length != right.Length) 
     { 
      return false; 
     } 

     for (int i = 0; i < left.Length; i++) 
     { 
      if (!left[i].Equals(right[i])) 
      { 
       return false; 
      } 
     } 

     return true; 
    } 
} 
1

配列が参照型は非常に平等のためのテストは、ポインタが同じであるかどうかを確認します。彼らはそうではありません。

配列自体ではなく要素を比較する場合は、import System.Linqとし、keya.SequenceEqual(keyb)を使用します。

+0

私の開発環境であるmonoでは利用できません。 – Ali

+0

@Ali:ああ、他の答えと同じように各要素を比較する必要があります。 –

+0

@Ali:Monoはかなりの間LINQ to Objectsをサポートしていると思います。 –

関連する問題