우선순위 - c#+연산자




과부하 연산자== 대 Equals() (4)

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

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

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

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

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

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


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

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


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

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


MSFT 지침 (아래)에 따라이를 구현하는 방법을 보여주는 샘플. 주목할 것은, Equals를 오버라이드 할 때 GetHashCode ()를 오버라이드해야한다는 것입니다. 희망이 여러분을 돕습니다.

public class Person
{
    public Guid Id { get; private set; }

    public Person(Guid id)
    {
        Id = id;
    }

    public Person()
    {
        Id = System.Guid.NewGuid();
    }

    public static bool operator ==(Person p1, Person p2)
    {
        bool rc;

        if (System.Object.ReferenceEquals(p1, p2))
        {
            rc = true;
        }
        else if (((object)p1 == null) || ((object)p2 == null))
        {
            rc = false;
        }
        else
        {
            rc = (p1.Id.CompareTo(p2.Id) == 0);
        }

        return rc;
    }

    public static bool operator !=(Person p1, Person p2)
    {
        return !(p1 == p2);
    }

    public override bool Equals(object obj)
    {
        bool rc = false;
        if (obj is Person)
        {
            Person p2 = obj as Person;
            rc = (this == p2);
        }
        return rc;
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }
}




equals