2009-06-28 6 views
1

일부 바이트 [] 비교를 수행하고 있습니다.2 바이트 배열 사이의 확장 메서드 "같음"을 원합니다.

나는 ==을 시도했지만이 기본이되는 같음처럼 : 그것은 간다,

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와 함께있었습니다 :-) –

+0

듣고 기뻐했습니다 ... – Shimmy

+2

Linq는 이미 당신이 묘사하는 것을 수행하는'SequenceEqual'이라는 내장 메소드를 가지고 있습니다 . – Juliet

답변

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

첫 번째 비 일반 메서드는 참조 평등과 무효 여부도 확인해야합니까? –

+0

@ 토미 : 가능한 한 원본에 가깝게 첫 번째 버전을 남기고 싶지만 더 많은 변화를 제공하는 더 완벽한 솔루션을 제공하고 싶습니다. –

+0

동등 비교를 수행하기 전에 null을 확인하는 것이 더 좋지 않습니까? 또는 두 개의 null 배열이 같다고 가정하면이 작업을 수행하고 있습니까? – ahawker

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로 시도 할 수 있음). 내 특별한 경우에는 단순한 가치 유형이 있습니다

+1

정말로 backwords .NET 버전을 사용하지 않는 한, 나는 왜이 대답을 가지고 난 후에 당신 자신을 귀찮게하는지 이해하지 못한다. http://stackoverflow.com/questions/1054459/i-wanna-have-an-extension-method-equals -between-2-byte-arrays/3106129 # 3106129 – Shimmy

+0

네. 닷넷 프레임 워크의 버전이 제한되어 있기 때문에 – sergiol