안녕하세요. BlockDMask 입니다.
오늘은 C#에서 Equals, ==, ReferenceEquals 설명과 차이점에 대해서 알아보겠습니다.
<목차>
1. Equals, ==, ReferenceEquals 설명
2. 값타입, 참조타입에 따라 다른 Equals, ==, ReferenceEquals 예제
1. ==, Equals, ReferenceEquals 설명
1-1) 같음 연산자 '=='
같음 연산자 == 는 연산자 왼쪽 오른쪽에 오는 것들이 같은지를 판단하는 연산자 입니다
값 타입의 경우 좌 우의 값이 같으면 True, 다르면 False 를 반환합니다.
참조 타입은 좌 우 객체가 같은지를 비교합니다.
(객체 내부의 값이 같은지 비교 한다는 뜻, 참조(주소)는 상관없음)
1-2) Equals 도 똑같이 == 과 동일한 역할을 합니다.
public virtual bool Equals(object? obj)
public virtual bool Equals(object? objA, object? objB)
Equals 메서드는 기본적으로 객체가 같은지를 비교합니다.
기본적으로는 == 과 동일한 작동을 합니다.
값 타입은 값이 같은지 비교를 하고
참조 타입은 객체가 같은지를 비교합니다.
(객체 내부의 값이 같은지 비교 한다는 뜻, 참조(주소)는 상관없음)
object 클래스의 Equals 를 보면 내부적으로 == 으로 비교하고 있는 것을 알 수 있습니다.
제가 위에서 "기본적"으로는 == 과 동일하다고 말씀드린 이유는 C#에서 기본적으로 정의된 Equals 는 == 과 동일한 작동을 합니다.
하지만 Equals를 보면 virtual 키워드가 있는것을 알 수 있습니다.
이것은 사용자(프로그래머)가 언제 어디서는 해당 메서드를 재정의(override)해서 사용할 수 있다는 뜻 입니다.
그렇기 때문에 "Equals 메서드는 기본적으로 == 과 동일한 역할을 하지만, 재정의에 따라서 어떤 동작을 할지 확신할 수는 없다." 가 맞을 것 같습니다.
"아니 그럼 참조만 확실하게 비교하고 싶은데 어떻게 해? => 요것은 아래 ReferenceEquals 를 이용하면 됩니다."
1-3) ReferenceEqual 메서드
public static bool ReferenceEquals(object? objA, object? objB)
첫번째 두번째 매개변수로는 비교하고자 하는 객체를 넣습니다.
두 객체의 참조가 같으면 True, 다르면 False 를 반환합니다.
ReferenceEquals는 진짜 해당 참조를 비교하는 메서드 (주소 비교)
위에서 Equals는 클래스 등에서 사용할때 Equals 를 각 클래스에 맞게 오버라이딩 해서 사용해야한다고 말씀드렸는데요.
ReferenceEquals는 오버라이딩 할 수 없습니다. (virtual 키워드가 없잖아요!)
그러니, 참조가 같은지 (주소가 같은지)를 비교할때는 이 ReferenceEquals를 사용하면 됩니다.
ReferenceEquals는 "참조(가리키는 주소)"가 같은지 확인하는 것 이기 때문에 값타입 비교는 항상 False 가 나오게 됩니다.
2. 값, 참조 타입에 따른 Equals, ==, ReferenceEqual 예제
2-1) 값 타입
값 타입을 보면 == , Equals 둘다 동일하게 그리고 당연하게 값을 비교 하게 됩니다.
값이 같으면 True, 다르면 False 당연하겠죠?
반면 ReferenceEquals 에서는 모두 False 가 나오게 됩니다. 값 타입에서는 ReferenceEquals는 무의미한 메서드 입니다.
제가 쓰는 IDE 에서 value 타입을 ReferenceEquals에서 사용하려 하면 "Object.ReferenceEquals' is always false because it is called with value type" 와 같이 value 타입에서는 항상 False 를 반환할 것이다. 라는 팁을 알려줍니다.
2-2) 참조 타입
a, b, c 문자열을 각각 생성해봤는데
a와 c는 참조도 같고 값도 같은 문자열이고
b는 참조가 a,c랑 다르지만, 값은 같은 문자열 입니다.
(b를 저렇게 선언한 이유는 C# 단에서"BlockDMask"를 동일하게 선언하는 경우 최적화를 통해서 동일한 참조를 가리킬 수 있기 때문입니다. 즉, 참조를 확실하게 다르게 하기 위해서 문자열을 조합해서 만들어 버린것.)
결과를 보면 string 타입에서 값이 같은지를 비교하려면 == 과 Equals를 쓰면 되고
실제 참조가 같은지를 비교하려고 하면 ReferenceEquals 를 사용하면 됩니다.
*주의 : Equals 메서드는 클래스 마다 override를 어떻게 했느냐에 따라 우리의 기대 결과 값이 다를 수 있습니다.
이상으로 오늘은 씨샵에서 Equals, ==, ReferenceEquals 을 통한 비교가 어떤 결과를 가지고 오는지 알아보았습니다.
감사합니다.
'<개인공부> > [C#]' 카테고리의 다른 글
[C#] out 매개변수 한정자 설명 및 예제 (out 키워드) (4) | 2022.11.05 |
---|---|
[C#] in 매개변수 한정자 설명 및 예제 (in 키워드) (5) | 2022.10.29 |
[C#] ref 매개변수 한정자 설명 및 에제 (ref 키워드) (0) | 2022.10.22 |
[C#] 확장 메서드 (Extension Method) 설명과 예제 (0) | 2022.10.15 |
[C#] 실행 시간 측정, 코드 수행 시간 측정(Stopwatch) (0) | 2022.09.25 |
[C#] const, readonly 설명 사용법과 차이점에 대해서 (0) | 2022.09.22 |
[C#] 타입 조사 Type, 리플렉션(reflection) (0) | 2022.09.11 |
[C#] 인덱서 객체(인스턴스)를 배열 처럼 사용해보자 (0) | 2022.09.04 |