1

私はいくつかのバイト[]比較を行っています。

== を試してみましたが、これは基本 Equals と同じです。

byte[] a = {1,2,3};
byte[] b = {1,2,3};
bool equals = a == b; //false
equals = a.Equals(b); //false

拡張メソッドを追加しようとしましたが、オーバーロードされた基本クラスの Equals は同じ引数を取るため、拡張ではなく基本メソッドに移動します。とにかく、Equals 拡張を使用できますか (名前を変更せずに...)または(さらに良い)==演算子を使用しますか?

これが私が実際に比較しなければならないものです:

public static bool ContentEquals(this byte[] array, byte[] bytes)
{
    if (array == null || bytes == null) throw new ArgumentNullException();
    if( array.Length != bytes.Length) return false;
    for (int i = 0; i < array.Length; i++)
        if (array[i] != bytes[i]) return false;

    return true;
}
4

3 に答える 3

8

拡張メソッドで演算子のオーバーロードを行うことはできません。メソッドに対して機能しない理由は、拡張メソッドを使用せずに適用可能Equalsメソッドがある場合、拡張メソッドが検査される前にそのメソッドが選択されるためです。

Equals引数の型を正式なパラメーターの型に変換するという点では、メソッドの方が「優れています」が、コンパイラは常に「通常の」メソッドを優先します。メソッドに別の名前を付ける必要があります。

ただし、メソッドはいつでも使用できますEnumerable.SequenceEquals。ただし、長さチェックを短絡させるとは思いません(ICollection<T>実装の場合は可能ですが)。ただし、より効率的なバージョンを自分でいつでも実装できます。実際、既存の配列の実装を単にSequenceEqualsorと呼ばれるように変更するだけであれば、それで問題ありませんArrayEquals

public static bool ArrayEquals(this byte[] array, byte[] bytes)
{
    // I'd personally use braces in all of this, but it's your call
    if (array.Length != bytes.Length) return false;
    for (int i = 0; i < array.Length; i++)     
        if (array[i] != bytes[i]) return false;

    return true;
}

ジェネリックにするのは非常に良いことですが、比較をインライン化できないため、パフォーマンスが少し低下することに注意してください。

public static bool ArrayEquals<T>(this T[] first, T[] second)
{
    // Reference equality and nullity checks for safety and efficiency
    if (first == second)
    {
        return true;
    }
    if (first == null || second == null)
    {
        return false;
    }
    if (first.Length != second.Length)
    {
        return false;
    }        
    EqualityComparer<T> comparer = EqualityComparer<T>.Default;
    for (int i = 0; i < first.Length; i++)
    {
        if (!comparer.Equals(first[i], second[i]))
        {
             return false;
        }
    }
    return true;
}
于 2009-06-28T07:32:19.770 に答える
6
using System.Linq;

byte[] a = {1,2,3}; 
byte[] b = {1,2,3}; 
bool same = a.SequenceEqual(b);
于 2010-06-23T22:50:59.653 に答える
0

私は同じ目的でこれを行いました:

static class Global
{
    public static bool ArraysAreEqual(Array arr1, Array arr2)
    {
        if (arr1.Length != arr2.Length)
            return false;

        System.Collections.IEnumerator e1 = arr1.GetEnumerator();
        System.Collections.IEnumerator e2 = arr2.GetEnumerator();

        while(e1.MoveNext() && e2.MoveNext())
        {
            if(!e1.Current.Equals(e2.Current))
                return false;
        }
        return true;
    }
}

ただし、参照型が等しい場合、 .Equals() は false を返すことさえあることに注意してください(テストはしませんでしたが、 StringBuilder で試すことができます)。私の特定のケースでは、単純な値の型しかありません

于 2010-07-13T16:47:09.530 に答える