2011-08-07 1 views
5

, 항등 연산자 오버로드의 System.Linq.Data.Binary 구현은 다음과 같습니다참조하는 평등 연산자는 반사판 또는 DotPeek를 사용

[Serializable, DataContract] 
public sealed class Binary : IEquatable<Binary> 
{ 
... 
    public static bool operator ==(Binary binary1, Binary binary2) 
    { 
     return ((binary1 == binary2) || (((binary1 == null) && (binary2 == null)) || (((binary1 != null) && (binary2 != null)) && binary1.EqualsTo(binary2)))); 
    } 

뭔가 분명 실종, 또는이되어야합니다 내가 인식하지 못하는 메커니즘 (예 : 본문 내에서 객체 ==를 암묵적으로 호출하는 것). 표준 운영자에게 과부하가 필요한 경우는 거의 없습니다.

왜이 구현은 무한 재귀를 초래하지 않습니다 (간단한 테스트에서 무한 반복되지 않음을 보여줍니다)? 첫 번째 조건식은 binary1 == binary2입니다. 구현 외부에서 binary1 == binary2를 사용하면 호출되는 operator overload 구현 내에서 생각할 수 있습니다.

답변

5

나는 이것이 디 컴파일러의 버그 일 것으로 기대합니다. Redgate Reflector에는 동일한 버그가 있었고, 나는 found it in ILSpy도 가지고 있습니다.

디 컴파일이 어려운 이유는 C# 오버로드 규칙을 미묘하게 테스트하기 때문입니다. 원래 코드는 (object)obj1==(object)obj2과 같았지만이 변환은 IL 자체에서 볼 수 없습니다. 모든 참조 유형을 기본 유형으로 유형 변환하는 것은 런타임과 관련하여 아무 작업도 수행하지 않습니다. 그러나 오버로드 된 항등 연산자를 호출하는 대신 참조 동등한 opcode를 선택하도록 C#을 설정합니다.

IMO 디 컴파일러에서이를 구현하는 올바른 방법은 참조 평등 검사를 항상 (object)obj1==(object)obj2으로 디 컴파일 한 다음 과부하 해결에 영향을주지 않으면 중복 된 캐스트를 최적화하는 것입니다. 이 방법은 메서드 오버로드와 비슷한 문제를 해결합니다.

2

ReSharper (및 dotpeek) 버전의 버그 일 가능성이 있습니다. ReSharper의 버전 6.0 (6.0.2202.688)은 올바르게 수행합니다 :

public static bool operator ==(Binary binary1, Binary binary2) { 
     if ((object)binary1 == (object)binary2) 
      return true; 
     if ((object)binary1 == null && (object)binary2 == null) 
      return true; 
     if ((object)binary1 == null || (object)binary2 == null) 
      return false; 
     return binary1.EqualsTo(binary2); 
    } 
+2

죄송합니다. Reflector는 Resharper가 아니라 내 게시물에 수정했습니다. 흥미로운 것은 현재의 Resharper가 올바르게 만들었지 만 DotPeek (같은 회사)는 그렇지 않습니다. – hatchet