2012-07-10 2 views
7

내 (단위) 테스트 커버리지가 여전히 매우 낮기 때문에 안타깝게도 많은 실수를 많이 겪어야합니다. 따라서 리팩토링 중에는 C# 컴파일러의 형식 검사에 크게 의존합니다.유형 안전 Equals()

오늘 리팩터링 중에 도입 된 버그는 x.Equals(aThingWrappingOriginalThing)이라는 줄을 누락하여 수정되었습니다. 그것은 bool Equals(object T)이므로 컴파일러는 불평하지 않았습니다. 그러나 Equals()을 (BCL 대신에) 직접 사용하는 시간의 90 %를 논리적으로 같은 유형의 개체와 비교하려고합니다.

이제는 (C#의) 이러한 상황에 대해 Equals()의 유형 안전 버전을 승격 한 사람을 본 적이없는 이유가 궁금합니다. 이것에 대한 모범 사례가 있습니까?

public static bool SafeEquals<T>(this T a, T b) 
{ 
    if (a == null) return b == null; 
    return a.Equals(b); 
} 
public static bool SafeEquals<X>(this IEquatable<X> a, IEquatable<X> b) 
{ 
    if (a == null) return b == null; 
    return a.Equals(b); 
} 

이 최적화 될 수 있습니다 :

나는과 같이, 그 comparisions에 대한 확장 방법을 사용하는 유혹 해요? http://rickyclarkson.blogspot.com/2006/12/making-equalsobject-type-safe.html

+0

주제에 대한 배경은 http://blogs.msdn.com/b/ericlippert/archive/2009/04/09/double-your-dispatch-double-your-fun.aspx – Vlad

답변

5

당신은

EqualityComparer<T>.Default.Equals(x,y); 

찾고있는이 IEquatable<T>가 (구현 된 경우), 다른 Equals(object) 잠재적 복싱 사용 지원; Nullable<T> (boxing하지 않음)에 대한 지원을 포함하여 모두에 대해 예상 된 null 동작을 사용하여 클래스 및 구조체를 지원합니다.

+0

감사합니다. 훌륭한 소리입니다. 확장 메서드로 래핑하기 위해 성능에 손상을 줍니까? 인라인 될 것인가? – Equalizer

+0

@Equalizer 확장 메서드는 static-call이므로 다음과 같습니다. .Default는 사용할 전략에 따라 여러 가지 구체적인 구현 중 하나의 인스턴스이기 때문에 기울어지지는 않을 것입니다. 결정/변경은 T 당 한 번만 수행되므로 캐시되지만 인라인되지는 않습니다. –

2

내가 보는 것은 나에게 좋아 보인다 :

는 여기에 내가 자바를 들어 볼 수있는 주제에 대한 유일한 블로그 게시물입니다.

내 2 센트 : 나는이 널 검사를 생략하고 사용하는 것이 더 간단하다고 생각 :

public static bool SafeEquals<T>(this T a, T b) 
{ 
    return object.Equals(a, b); 
} 

하는 것은 그 의도 행동에서 벗어난 것이다 매우 몇 가지 경우가 있습니다. 그 중 하나는 Equals이 두 객체가 같은 객체 인 경우 false를 반환하는 경우입니다. 어쨌든 결코 발생하지 않아야합니다.

참고로 여기에 디 컴파일 된 object.Equals이 있습니다. 따라서 어떤 일이 발생하는지 직접 볼 수 있습니다.

public static bool Equals(object objA, object objB) 
{ 
    return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB))); 
} 
+0

'개체입니다. 같음'은 둘 다 힙의 동일한 데이터를 가리키는 지 확인합니다. –

+0

@Kendall 여기서 첫 번째 구현은 객체에 대한 래퍼입니다 .Equals는이를 위해 소비자가 객체를 호출하게하는 것이 무엇이겠습니까? – Jason

+0

@ColeJohnson의 기본값 일 수 있습니다. 그러나 'Equals'와 'ReferenceEquals'의 차이점은 무엇입니까? –

관련 문제