문제

.Equals를 사용하는 것과 == .NET 4.0의 새로운 튜플 <> 인스턴스 사이에서 다른 동작을보고 있습니다. 튜플 <>의 객체에서 비정규 한 경우 튜플에서 .equals를 호출하면 평등의 재정의가 호출됩니다. 튜플에서 ==를 사용하면 평등의 재정의가 호출되지 않습니다. 그것은 디자인에 의해 의미가 있습니까?

편집하다: 답과 의견에서 나는 명확하지 않다고 말할 수 있습니다. 튜플 <>은 참조 유형이며 참조 유형의 경우 ==는 Identity (참조 equals)를 확인합니다. 그러나 튜플 <>을 재정의 == 포함하는 물체의 평등을 확인해야합니까? 일관성을 위해, 아마도.

예를 들어 간단한 개체가있는 경우

public class NameAndNumber
{
    public int Number { get; set; }
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is NameAndNumber)
        {
            NameAndNumber other = (NameAndNumber)obj;
            return Number == other.Number && Name == other.Name;
        }

        return false;
    }
}

그런 다음 다음과 같은 일을합니다.

Tuple<NameAndNumber, NameAndNumber> left = new Tuple<NameAndNumber, NameAndNumber>(
      new NameAndNumber { Name = "one", Number = 1 }, 
      new NameAndNumber { Name = "two", Number = 2 });
Tuple<NameAndNumber, NameAndNumber> right = new Tuple<NameAndNumber, NameAndNumber>(
      new NameAndNumber { Name = "one", Number = 1 }, 
      new NameAndNumber { Name = "two", Number = 2 });
bool operatorResult = left == right;
bool equalsResult = left.Equals(right);
Console.Out.WriteLine("operatorResult = {0}  equalsResult = {1}", 
        operatorResult, equalsResult);

OperatorResult = False EqualSresult = true를 얻습니다

내가 그것을 기대해야합니까?

Nameandnumber에서 Equals의 구현이 단순화 된 샘플 코드라는 것을 알고 있습니다.

또한 iquateable, ==,! = 및 gethashcode를 구현하려고 시도했습니다. 동일한 결과.

도움이 되었습니까?

해결책

당신이 보는 결과는 a 디자인 타협, 튜플은 이제 F#과 C# 사이에서 공유됩니다. 요점은 모든 튜플이 실제로 참조 유형으로 구현되며, 그렇게 명백하지는 않았다는 것입니다.

튜플이 깊거나 얕은 평등 점검을 수행 해야하는지 결정은 두 개의 인터페이스로 이동되었습니다. IStructuralComparable, IStructuralEquatable. 이 2는 이제 배열 클래스에서 구현됩니다.

다른 팁

참조 유형의 경우 : ==는 ID 비교를 수행합니다. 즉, 두 참조가 동일한 객체를 가리키는 경우에만 TRUE를 반환합니다. equals () 메소드는 값 비교를 수행 할 것으로 예상되지만, 참조가 동등한 객체를 가리키면 true를 반환합니다.

참조 유형의 경우 == 아니다 과부하가 지나면 두 참조가 동일한 개체를 참조하는지 여부를 비교합니다.

기본적으로 연산자 == 참조 평등을 테스트하므로 당신이보고있는 결과가 예상됩니다.

보다 Equals () 및 Operator == (C# 프로그래밍 안내서)를 재정의하기위한 지침:

C#에는 두 가지 종류의 평등이 있습니다 : 참조 평등 (정체성이라고도 함)과 가치 평등. 가치 평등은 평등의 일반적으로 이해되는 의미입니다. 그것은 두 객체에 동일한 값을 함유한다는 것을 의미합니다. 예를 들어, 2의 값을 가진 두 개의 정수는 값 평등을 갖습니다. 참조 평등은 비교할 객체가 두 개나 없음을 의미합니다.

기본적으로, == (클래스에서) 참조 평등을 의미합니다. 즉, 동일한 사례입니다. 무엇 object.ReferenceEquals(x,y) 돌아올 것입니다.

자신만의 == /! = 운영자를 제공하여 예상되는 동작을 얻을 수 있습니다. Equals 무시하는 것이 중요합니다 GetHashCode 너무 (그렇지 않으면 사용을 열쇠로 깨뜨립니다. C#에서 Equals 메소드를 재정의 할 때 GethashCode를 무시하는 것이 중요한 이유는 무엇입니까?):

public static bool operator == (NameAndNumber x, NameAndNumber y) {
    if (x == null && y == null) return true;
    if (x == null || y == null) return false;
    return x.Number == y.Number && x.Name == y.Name;
    // or if polymorphism is important: return x.Equals(y);
}
public static bool operator !=(NameAndNumber x, NameAndNumber y) {
    return !(x == y); // lazy but works
}
public override int GetHashCode() {
    return (Name == null ? 0 : Name.GetHashCode()) +
        17 * Number.GetHashCode();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top