私は2つのバイト配列の間で「等しい」拡張メソッドを持っていたいです

StackOverflow https://stackoverflow.com/questions/1054459

質問

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

私は==試みたが、これはベースが等しいだけのようなものです、これます:

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

私はとにかく私が使用できる拡張メソッドを追加しようとしましたが、同じ引数を取るオーバーロードされた基本クラスは等しいことから、それは内線に、むしろ基本法に行き、そこにあるそれは名前の変化するwthout(拡張子は等しいです。 ...)または(より良い)を使用==演算子?

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

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;
}
役に立ちましたか?

解決

using System.Linq;

byte[] a = {1,2,3}; 
byte[] b = {1,2,3}; 
bool same = a.SequenceEqual(b);

他のヒント

あなたは確かに拡張メソッドと演算子オーバーロードを行うことはできません。それはEquals方法で動作しない理由は、もしのいずれかのの方法は、その方法は、拡張メソッドがさえ検討される前に選択されます拡張メソッドを使用せずに適用されます。

あなたのEquals方法は、仮パラメータの型に引数の型を変換するという点で「より良い」であっても、コンパイラは常に「正常な」方法を好みます。あなたはあなたの方法に別の名前を付ける必要があります。

しかし、あなたは常にEnumerable.SequenceEqualsメソッドを使用することができます。私は信じていないという短絡(ICollection<T>の実装のためにも、それはできるけれども、)ただし長チェック。あなたはいつもかかわらず、より効率的なバージョンを自分で実装することができます。あなたは自分の既存のアレイの実装を変更した場合確かに、SequenceEqualsあるいは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;
}

私は、同じ目的のためにこれをしませんでした

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(ことに注意)、彼らが等しい場合でも、(私がテストしていないが、あなたはStringBuilderので試すことができます)を参照-タイプにfalseを返すことがあります。私の特定のケースでは私は単純な値、タイプ

を持っています
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top