c# 우선순위 - 과부하 연산자==대 Equals()




느낌표 operator (6)

저는 지금까지 Foo 타입의 객체가 항상 == 와 같은지 비교 될 수 있도록하기 위해 불변 객체와 팩토리를 사용했던 C # 프로젝트를 만들고 있습니다.

Foo 객체는 일단 생성되면 변경할 수 없으며 팩토리는 주어진 인수 세트에 대해 항상 동일한 객체를 반환합니다. 이것은 훌륭하게 작동하며, 코드베이스 전체에서 == 항상 평등을 검사하는 것으로 간주합니다.

이제는 항상 작동하지 않을 수있는 엣지 케이스를 도입하는 몇 가지 기능을 추가해야합니다. 가장 쉬운 방법은 해당 유형에 대해 operator == 를 오버로드하여 프로젝트의 다른 코드를 변경하지 않아도되도록하는 것입니다. 하지만 이것은 코드 냄새로 나를 강타합니다 : Equals 아닌 Equals operator == 오버로드되면 이상한 것처럼 보이고, == 는 참조 평등을 검사하고 Equals 는 객체 평등을 검사합니다 (또는 용어가 무엇이든간에).

이것은 합법적 인 관심사입니까, 아니면 그냥 앞에 operator == 오버로드해야합니까?


Answers

Microsoft의 모범 사례에 따르면 Equals 메서드와 equals (==) 오버로드의 결과는 동일해야합니다.

CA2224 : 오버플로 연산자 equals에서 오버라이드 equals


불변 타입의 경우 값 평등을 지원하기 위해 과부하가 == 생각하지 않습니다. 그러나 같은 의미를 갖기 위해 Equals 를 재정의하지 않고 == 를 재정의한다고 생각하지 않습니다. == 재정의하고 어떤 이유로 든 참조 동등성을 검사해야하는 경우 Object.ReferenceEquals(a,b) 사용할 수 있습니다.

유용한 가이드 라인 은이 Microsoft 문서를 참조하십시오.


확실히 냄새가 난다. 오버로드 ==Equals()GetHashCode() 가 모두 일관성이 있는지 확인해야합니다. MSDN 가이드 라인을 참조하십시오.

그리고 이것이 전혀 괜찮은 유일한 이유는 타입을 불변으로 기술한다는 것입니다.


오버로드 ==오버라이드 Equals에는 큰 차이가 있습니다.

당신이 표현을 가지고있을 때

if (x == y) {

변수 x와 y를 비교하는 데 사용할 메소드는 컴파일 타임에 결정됩니다. 이것은 연산자 오버로딩입니다. x 및 y를 선언 할 때 사용되는 유형은이를 비교하는 데 사용되는 메소드를 정의하는 데 사용됩니다. x와 y 내의 실제 타입 (즉, 서브 클래스 또는 인터페이스 구현)은 부적합하다. 다음을 고려하세요.

object x = "hello";
object y = 'h' + "ello"; // ensure it's a different reference

if (x == y) { // evaluates to FALSE

다음

string x = "hello";
string y = 'h' + "ello"; // ensure it's a different reference

if (x == y) { // evaluates to TRUE

이것은 변수 x 및 y를 선언하는 데 사용되는 유형이 ==을 평가하는 데 사용되는 메소드를 결정하는 데 사용됨을 보여줍니다.

이에 비해 Equals는 변수 x 내의 실제 유형을 기반으로 런타임에 결정됩니다. Equals는 Object의 가상 메서드이며 다른 형식으로 재정의하거나 재정의 할 수 있습니다. 따라서 다음 두 예제는 모두 true로 평가됩니다.

object x = "hello";
object y = 'h' + "ello"; // ensure it's a different reference

if (x.Equals(y)) { // evaluates to TRUE

다음

string x = "hello";
string y = 'h' + "ello"; // ensure it's a different reference

if (x.Equals(y)) { // also evaluates to TRUE

나는 표준이 대부분의 유형에있어서, .Equals는 객체 유사성을 검사하고 operator == 는 참조 평등을 검사한다고 믿는다.

가장 좋은 방법은 불변 타입의 경우 연산자 ==.Equals 뿐만 아니라 유사성을 검사해야한다는 것입니다. 그리고 그들이 정말로 같은 대상인지 알고 싶다면 .ReferenceEquals 사용하십시오. 이에 대한 예제는 C # String 클래스를 참조하십시오.


정말 좋은 답변과 예제!

나는이 둘의 근본적인 차이점을 추가하고 싶다.

== 와 같은 == 는 다형성이 아니지만 Equals 는입니다.

이 개념을 염두에두고 어떤 예제를 사용하면 (왼손잡이와 오른손 참조 유형을보고 유형에 실제로 과부하가 걸리고 Equals가 재정의되었는지 확인하고 확인하면 올바른 대답을 얻을 수 있습니다. .





c# operator-overloading equals