2009-06-28 31 views
1

我正在做一些字節[]比較。我想有一個擴展方法「等於」2字節數組之間

我試圖==但這就像基地的Equals,其中:

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

我嘗試添加一個擴展方法,但由於過載基站類等於採取相同的參數,它進入基本的方法,而不是擴展,有無論如何,我可以使用一個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; 
} 
+0

無可挑剔的時機!我今天早上想要做同樣的事情,你和Skeet在Q/A那裏:-) – 2009-06-29 13:38:13

+0

很高興聽到...... – Shimmy 2009-07-01 00:14:35

+2

Linq已經有一個名爲`SequenceEqual`的內置方法,它完全符合你的描述。 – Juliet 2010-06-23 22:54:57

回答

6
using System.Linq; 

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

你肯定做不到運營商擴展方法重載。它不適用於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; 
} 
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嘗試)。在我的特殊情況下,我只有簡單的價值類型