2012-03-19 3 views
8
 string s1 = "t"; 
     string s2 = 't'.ToString();   

     Console.WriteLine(s1.Equals(s2)); // returning true 
     Console.WriteLine(object.Equals(s1, s2)); // returning true 

여기는 같은 결과를 반환합니다. 이제 StringBuilder를 사용할 때 같은 값을 반환하지 않습니다. 밑에있는 이유는 무엇입니까?왜 object.Equals와 instanceobject.Equals가 같지 않음

 StringBuilder s1 = new StringBuilder(); 
     StringBuilder s2 = new StringBuilder(); 

     Console.WriteLine(s1.Equals(s2)); // returning true 
     Console.WriteLine(object.Equals(s1, s2)); // returning false 

EDIT1 : 아래의 응답 내 위의 질문입니다. 그러나이 토론에서 StringBuilder는 구현시 Equals 메서드를 재정의하지 않습니다. 그래서 우리는 StringBuilder.Equals를 호출 할 때 실제로 Object.Equals로갑니다. 따라서 누군가가 StringBuilder.Equals와 S1.Equals (S2)를 호출하면 결과가 달라집니다. 그들은 이러한 StringBuilder 같은 참조 타입 참조 평등 있다면

+1

좋은 캐치! 요컨대,'StringBuilder'는'Equals (object)'를 오버라이드하는 것을 잊어 버리는 것 같습니다. 'Equals (StringBuilder)'가 'Equals (object)'와 다른 동작을하는 것은 직관력이없는 것처럼 보입니다. – leppie

답변

7

String.Equals()Equal() override가 string에 정의 된 경우 동일한 문자열이 실제로 Equal()이되도록 C#에서 오버라이드됩니다.

당신이 string literals (하지 귀하의 예제의 경우)를 비교하는 경우, 그것은 ... 즉, 동일한 문자열이 너무도 참조로 동일 해집니다 같은 주소에 살고 동일한 문자열 리터럴이 interned 것을 주목할 필요 (예 : 객체 .Equals() 또는 s1.ReferenceEquals (s2))뿐만 아니라 값으로.

StringBuilder의 매개 변수로하여 StringBuilder 소요 Equals()에 과부하 (즉 s1.Equals(s2) 대신 object.Equals(object obj) 호출의 과부하를 호출이다)를 제공한다.

http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.equals.aspx

StringBuilder.Equals()는 ...

인스턴스와 SB가 동일한 문자열, 용량 및 MAXCAPACITY 값이

true 인 경우; 그렇지 않으면 false입니다.

object.Equals()는 (a 등급을 통과하는 경우)에만 참조 어떤지 검사 static Equals() defined on object 또는 value equality 위해 사용 (구조체를 통과하는 경우).

그래서 요약

string s1 = "t"; 
string s2 = 't'.ToString();   

Console.WriteLine(s1.Equals(s2)); // true because both reference equality (interned strings) and value equality (string overrides Equals()) 
Console.WriteLine(object.Equals(s1, s2)); // true because of reference equality (interned strings) 

StringBuilder s1 = new StringBuilder(); 
StringBuilder s2 = new StringBuilder(); 

Console.WriteLine(s1.Equals(s2)); // true because StringBuilder.Equals() overloaded 
Console.WriteLine(object.Equals(s1, s2)); // false because the two StringBuilder instances have different addresses (references not equal) 
+5

기술적으로 StringBuilder는 가상 객체를 재정의하지 않고 Equals 메서드 만 오버로드합니다 .Equals (object). 이것이 두 가지 방법이 다르게 작동하는 이유입니다. 나는 그들이 NET1.0에서 그것을 잊어 버리고 급격한 변화를 소개하고 싶지 않았을까? – alexm

+0

@alexm : 잘 잡으세요. 나는 전에 그것을 알아 채지 못했습니다. 내 대답이 업데이트되었습니다. –

+0

좋은 설명을위한 탁신 에릭. 작은 요약을 만들면 : object.Equals는 입력 개체 유형에 따라 참조 또는 값을 확인합니다. 반면 String 및 StringBuilder에는 해당 구현에 따라 작동하는 자체 오버로드/재정의 Equal 메서드가 있습니다. 내가 틀렸다면 나를 바로 잡아주세요. –

1

generic Equals method 보는 두 객체의 레퍼런스를 비교한다. 값 유형의 경우 string은 값 유형 (동작하지 않음)처럼 동작하며 비트 단위의 비교 (이진 표현이 동일한 지 여부가 결정됨)을 수행합니다. 그러나이 기능은 StringBuilder 클래스에서 오버로드됩니다.

  • 문자열
  • 용량
  • MAXCAPACITY,

따라서 S1을 : 모두 모두 StringBuilder 개체에 대한 다음과 같은 기준이 동일한 경우

MSDN에 따르면, 모두 StringBuilder의 동일한 메소드는 true를 돌려줍니다 두 번째 예제의 s2는 참조 참조 동등성을 실패하지만 방금 언급 한 기준에 따라 사용자 지정 StringBuilder Equals 동등성을 전달합니다.

+0

String은 값 유형이 아닙니다. (값 의미와 참조 ​​유형입니다.) http://stackoverflow.com/questions/1069155/is-string-a-value-type-or-a-reference-type –

+0

@BradleyGrainger, 나는 그것이 아니라는 것을 알고있었습니다. 기술적으로는 값 유형이지만이 경우에는 동일하게 작동합니다. 나는 분명히하기 위해 내 대답을 업데이 트됩니다. 감사. – Matt

1

문자열 클래스가 구현은 문자열의 값을 비교하는 방식으로 같음.

다른 유형의 비교를 구현하지 않는 한 대부분의 객체 인스턴스는 참조이 동일한 지 확인합니다.

정확히 동일한 값을 포함하는 두 개의 다른 문자열 상수가 컴파일러에 의해 동일한 객체 참조에 처음 할당되는 경우도 있습니다.

관련 문제