Frage

Ich mache einige byte [] Vergleiche.

Ich habe versucht == aber dies ist genau wie die Basis Equals, die:

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

Ich habe versucht, eine Erweiterungsmethode hinzufügen, aber da die überlastete Basisklasse nimmt Equals die gleichen Argumente, geht es an die Basismethode eher auf die Verlängerung, ist es trotzdem kann ich eine Erweiterung Equals (wthout ändert seinen Name. ..) oder (noch besser) verwenden Operator ==?

Hier ist, was ich eigentlich vergleichen:

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;
}
War es hilfreich?

Lösung

using System.Linq;

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

Andere Tipps

Sie können sicherlich nicht tun Operator mit Erweiterungsmethoden zu überlasten. Der Grund ist es nicht für die Equals Methode funktioniert ist, dass, wenn jeder Verfahren ist anwendbar ohne Erweiterungsmethoden zu verwenden, wird diese Methode gewählt werden, bevor Erweiterungsmethoden selbst untersucht werden.

Auch wenn Ihre Equals Methode „besser“ in Bezug auf der Umwandlung die Argumenttypen auf den formalen Parameter-Typ ist, der Compiler immer „normal“ Methoden bevorzugt. Sie werden Ihre Methode einen anderen Namen geben.

Sie können jedoch immer die Enumerable.SequenceEquals Methode verwenden. Ich glaube nicht, dass Kurzschlüsse die Längenprüfung aber (obwohl es könnte, für ICollection<T> Implementierungen). Man konnte immer eine effizientere Version selbst wenn implementieren. Ja, wenn Sie nur Ihre vorhandene Array Implementierung ändern SequenceEquals oder sogar ArrayEquals genannt zu werden, das wäre in Ordnung:

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

Beachten Sie, dass es ganz schön wäre es generisch zu machen, aber das wäre sicherlich ein wenig Leistung kosten als der Vergleich nicht inlined werden:

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

Ich tue dies für den gleichen Zweck:

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

aber feststellen, dass die .Equals () kann auch false zurück auf Referenz-Typen, wenn sie gleich sind (ich den Test nicht tat, aber Sie können mit String versuchen). In meinem Fall habe ich nur einfache Werttypen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top