HaPpY hApPy
9. ReferenceEquals(), static Equals(), instance Equals(), operator== 의상호연관성의 이해 본문
9. ReferenceEquals(), static Equals(), instance Equals(), operator== 의상호연관성의 이해
juniguya 2014. 3. 16. 12:461. c#에서 두개의 객체가 동일한가 확인하기 위한 4가지 메서드가 존재.
public static bool ReferenceEquals (object left, object right);
public static bool Equals(object left, object right);
public virtual bool Equals(object right);
public static bool operator ==(MyClass left, MyClass right);
1. 여러개가 존재하는 이유
+ Value 타입과 Reference Type 때문에
- Reference Type 은 같은 주소를 가지고 있어야 동일함
- Value는 같은 주소는 아니라도 같은 값을 가지면 동일함
2. 재정의 하면 안되는 함수 2개
1. 1,2 번째는 절대 재 정의하면안됨.
A. ReferenceEquals 는 Value, Reference Type에 상관없이 동일한 객체 참조 할 경우 true
주의 Boxing에 의한 주소 변환
int i = 5;
if (Object.ReferenceEquals(i, i))
Console.WriteLine("Never happens.");
else
Console.WriteLine("Always happens.");
* 위 결과는 항상 false 인데 이유는 i가 value type 이기 때문에 boxing 이 된 이후에 비교가 이루어지는데 여기서 boxing이 두번 일어나고 각 각 다른 heap영역 (주소)에 저장되기 때문에 동일한 reference를 참조하지 않음!
B. public static bool Equals() 재정의 하면안됨 이 함수는 내부적으로 정상적으로 instance Equals() 와 operator == 를 사용하기 때문에 사용자가 절대 제 정의 해서는안된다.
public static new bool Equals(object left, object right)
{
// Check object identity
if (Object.ReferenceEquals(left, right) )
return true;
// both null references handled above
if (Object.ReferenceEquals(left, null) || Object.ReferenceEquals(right, null))
return false;
return left.Equals(right);
}
C. Instance 형 Object.Equals()
+ Reference Type의 경우 Object.ReferenceEquals()와 완전 동일
+ 하지만 사용자가 재 정의 가능
- e.g. string의 경우 서로 Reference가 달라도 문자열이 동일하면 Equals() 가 true 리턴
+ Value Type의 경우 재 정의 해주는게 좋음
- Value Type경우 공통 상위 타입인 System.ValueType이 Object 타입의 Instance Equals()를 재정의 함
- 내부적으로 Reflection을 사용하여 수행성능에 영향을 끼침
전형적인 Instance 형 Object.Equals() override 방법
public class Foo : IEquatable<Foo>
{
public override bool Equals(object right)
{
// check null:
// this pointer is never null in C# methods.
if (object.ReferenceEquals(right, null))
return false;
if (object.ReferenceEquals(this, right))
return true;
// Foo를 상속받는 클래스로인해 인해 잘못된 비교가 이루어 질수 있기 때문에 this 의 Type을 가지고 비교해야 정확한 비교가 된다.
if (this.GetType() != right.GetType())
return false;
// Compare this type's contents here:
return this.Equals(right as Foo);\
}
#region IEquatable<Foo> Members
public bool Equals(Foo other)
{
// elided.
return true;
}
#endregion
}
D. 4번째 operator == 도 value 타입일 경우는 성능상의 문제로 재 정의 하는것이 좋다.
'.NET > Effective C#' 카테고리의 다른 글
10 GetHashCode()의 함정 (0) | 2014.03.16 |
---|---|
8. Value 타입을 사용할 때 0이라는 값이 의미를 가질수 있도록 (0) | 2014.03.16 |
7. immutable atomic value 타입이 더 좋다. (0) | 2013.08.17 |
6. value 타입과 reference 타입을 구분하라. (0) | 2013.08.17 |
5. 항상 ToString()을 작성하라. (0) | 2013.08.17 |