2012-02-16 2 views
3

C#의 문자열 클래스에서 비교 연산자로 구현 된 코드를 살펴 보았습니다. 무엇을 발견하는 것은이었다이 :문자열 등호 연산자 == in C#

//THIS IS NOT WHAT I MEANT 
public static bool Equals(object objA, object objB) 
{ 
    return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB))); 
} 

//THIS IS WHAT I SEE REALLY and the above is what I would expect to see 
public static bool Equals(string a, string b) 
{ 
    return ((a == b) || (((a != null) && (b != null)) && EqualsHelper(a, b))); 
} 



public static bool operator ==(string a, string b) 
{ 
    return Equals(a, b); 
} 

나는 그것이 나 트릭을 재생 반사경인지 모르겠지만, 나는 내 자신의 클래스에 대한이 전략을 구현하려고 할 때, 나는 같음 사이에 무한 루프를 가지고와 오버로드 된 == 연산자 (예상대로). 문자열 클래스에서 sth가 다른지 또는보고하는 리플렉터입니까

static Equals(object o1, object o2) 

메서드가 String 클래스의 일부가 될 Object 클래스에 있습니까?

+0

다음 == 연산자를 사용하지 않는? 인스턴스 메서드이기 때문에 정적 Equals 메서드와 같을 수 없습니다. 당신이 제공 한 코드를 기반으로, 나는 무한 루프를 보지 못했다. 우리가 인스턴스 Equals 메서드를 보여줄 수 있습니까? – ken

+0

죄송합니다.이 질문에 대한 업데이트를 작성했습니다. 잘못된 정의를 게시했습니다 ... – Bober02

+1

내 opnion에서 무한한 것은 (a == b)가 Equals (문자열 a, 문자열 b)에서 호출 될 때 발생합니다. STATIC 타입의 a와 b는 문자열이므로 Overloaded 연산자 ==가 호출됩니다. 간단한 예제에서 이것을 확인했는데 여기에 sth가 있는지 여부는 여기에서 보지 못했습니다. 아니면 반사체입니다. – Bober02

답변

6

C#의 항등 연산자는 다형성이 아닙니다. objA == objB을 계산할 때 objAobjB 변수의 선언 된 형식이 string이 아니기 때문에 이 아닌 연산자 구현 (참조 평등을 확인)이 실제로 실행됩니다.

코드에서 오류가 발생하는 경우 object으로 클래스 인스턴스를 캐스팅하지 않아야 == 연산자를 평가할 수 있습니다. 당신을 가정

가 있습니다

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

업데이트 :에 해당

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

... :

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

... 당신이 그것을 대체해야 할 것 String 클래스에는 봇이 포함되어 있습니다. h a static bool Equals(string a, string b) 방법 a static bool Equals(object a, object b) 방법. 차이점은 앞은 String 클래스 내에서 정의되고 후자는 Object 클래스 (기본 클래스는 String)에서 상속된다는 것입니다. 리플렉터는 설정에 따라 상속 된 메서드를 표시하거나 표시하지 않을 수 있습니다. 게시 된 코드에서

, objAobjB의 선언 된 유형에 관계없이 인스턴스의 실제 유형, 다음 object 매개 변수를 사용하여 운전자가 전화를받을 것 object 때문이다.

업데이트 : 업데이트 된 코드가 무한 재귀를 포함하는 것처럼 보인다. 반사 도구 내에서 버그 일 수 있다고 가정합니다.

업데이트 : 이것은 disassember의 버그 인 것 같습니다. Equals(string a, string b) 연산자 구현의 첫 번째 조건은 디스 어셈블 된 C# 코드에서 a == b으로 표시됩니다. 그러나, IL 코드의 처음 몇 줄 실제로 :

ldarg.0 
ldarg.1 
bne.un.s IL_0006 

ldc.i4.1 
ret 

bne.un.s 지정된 두 개의 부호없는 정수 값이 동일 (서명 값)이 아닌 경우, 오프셋 약식에서 타겟 명령을 브랜치 "로서 정의된다. "

따라서 참조 평등이 모두 수행되고있는 것처럼 보입니다.

+0

그건 사실이야! 하지만 반성 한 반에는 그것을 가지고 있지 않습니다 ... – Bober02

+0

나는 정말로 혼란 스럽습니다.아마도 다음 코드가 실행됩니다. – Bober02

+0

string a = "aaaa"; 문자열 b = "bbbb"; – Bober02

7

String.Equals(object, object) 방법이 없습니다.
Object.Equals이 표시됩니다.

다시 발생하지 않는 이유는 objA == objB이 사용자 지정 문자열 같음 연산자가 아니라 기본 제공 개체 같음 연산자를 호출하기 때문입니다.
(조작자 과부하가 피연산자의 컴파일 시간 유형에 따라 해결된다)

+0

어떤면에서는'String.Equals (object, object)'메소드가 있습니다. 'String' 클래스에서는 정의되지 않았지만'Object' 클래스에서 상속되었습니다. – Douglas

+0

네,하지만 광산에는 문자열의 매개 변수 유형이 있습니다. 오버로드 된 == 연산자를 다시 호출하면이 메서드는 Equals 메서드를 다시 호출합니다. – Bober02

+0

@Douglas 정적 메서드는 상속되지 않습니다. 'String.Equals (object, object)'를 호출 할 수 없습니다. 정적'Object.Equals (object, object)'메쏘드는 문자열 클래스의 * 범위 안에 있으므로,'Object.' 부분없이 호출 될 수 있습니다 만, 상속받지 않습니다. – phoog

0

는이 방식이다 지칭 같다 :

public static bool Equals(string a, string b) 
{ 
    /* == is the object equals- not the string equals */ 
    return a == b || (a != null && b != null && string.EqualsHelper(a, b)); 
} 

public static bool operator ==(string a, string b) 
{ 
    return string.Equals(a, b); 
} 

즉 2 개의 객체는 아니고 2 개의 캐릭터 라인을받는 equals 메소드

1

덜 혼란 솔루션 : 반사경이 objA.Equals 방법에 대해 할 말이 무엇을

public static bool Equals(MyClass a, MyClass b) 
{ 
    return ReferenceEquals(a, b) 
     || ((!ReferenceEquals(a, null) && !ReferenceEquals(b, null)) && a.Equals(b))); 
}