C#의 가치 평등을위한 사용자 정의 클래스의 가장 강력한 구현과 동일합니다.

StackOverflow https://stackoverflow.com/questions/570560

  •  05-09-2019
  •  | 
  •  

문제

Point2 클래스가 있다고 말하면 다음과 같은 동일을 구현하고 싶습니다.

public override bool Equals ( object obj )

public bool Equals ( Point2 obj )

이것은 효과적인 C# 3 책에서 나온 것입니다.

public override bool Equals ( object obj )
{
    // STEP 1: Check for null
    if ( obj == null )
    {
        return false;
    }

    // STEP 3: equivalent data types
    if ( this.GetType ( ) != obj.GetType ( ) )
    {
        return false;
    }
    return Equals ( ( Point2 ) obj );
}

public bool Equals ( Point2 obj )
{
    // STEP 1: Check for null if nullable (e.g., a reference type)
    if ( obj == null )
    {
        return false;
    }
    // STEP 2: Check for ReferenceEquals if this is a reference type
    if ( ReferenceEquals ( this, obj ) )
    {
        return true;
    }
    // STEP 4: Possibly check for equivalent hash codes
    if ( this.GetHashCode ( ) != obj.GetHashCode ( ) )
    {
        return false;
    }
    // STEP 5: Check base.Equals if base overrides Equals()
    System.Diagnostics.Debug.Assert (
        base.GetType ( ) != typeof ( object ) );

    if ( !base.Equals ( obj ) )
    {
        return false;
    }

    // STEP 6: Compare identifying fields for equality.
    return ( ( this.X.Equals ( obj.X ) ) && ( this.Y.Equals ( obj.Y ) ) );
}

그게 과잉입니까?

도움이 되었습니까?

해결책

상속 계층 구조로 평등을 지원하는 것은 까다 롭습니다. 당신은 당신이 의미하는 바를 정확하게 해결해야합니다. 여기서 상속 재산이 정말로 필요합니까? 그렇지 않은 경우 -Point2가 System.Object에서 직접 파생되고 밀봉되면 삶이 조금 쉬워집니다. 이 경우 나는 다음을 사용합니다.

public override bool Equals (object obj)
{
    return Equals(obj as Point2);
}

public bool Equals (Point2 obj)
{
    // STEP 1: Check for null if nullable (e.g., a reference type)
    // Note use of ReferenceEquals in case you overload ==.
    if (object.ReferenceEquals(obj, null))
    {
        return false;
    }

    // STEP 2: Check for ReferenceEquals if this is a reference type
    // Skip this or not? With only two fields to check, it's probably
    // not worth it. If the later checks are costly, it could be.
    if (object.ReferenceEquals( this, obj))
    {
        return true;
    }

    // STEP 4: Possibly check for equivalent hash codes
    // Skipped in this case: would be *less* efficient

    // STEP 5: Check base.Equals if base overrides Equals()
    // Skipped in this case

    // STEP 6: Compare identifying fields for equality.
    // In this case I'm using == instead of Equals for brevity
    // - assuming X and Y are of a type which overloads ==.
    return this.X == obj.X && this.Y == obj.Y;
}

다른 팁

실제로는 아닙니다 - 당신은 거의 모든 가능성을 설명하고 있습니다. 이 코드가 스크래치 응용 프로그램 이외의 다른 용인이라면 이상한 물체 평등 동작으로 인한 논리적 오류가 디버그에 고통 스럽기 때문에이 접근법의 이점을 고려해야합니다.

당신이 원하는 것을 정확히 좋아해요. 전체 블록은 다음으로 요약됩니다.

"정확히 동일한 인스턴스 인 경우 TRUE를 반환하십시오. 동일한 x 및 y 값을 가진 별도의 인스턴스 인 경우 true를 반환하십시오. 다른 모든 경우 (널, 다른 유형, 다른 x/y 값)는 false를 반환합니다."

확실히 코드가 더 많습니다 ID 평등 방법을 작성하고 싶습니다. 참조와 해시 코드를 확인하는 것과 같은 중복 점검이 많이 있습니다 (기능의 마지막 줄이 구조적 평등을 확인하기 때문에 이러한 점검이 중복되어 있음을 알고 있습니다). 간단하고 읽을 수있는 코드에 중점을 둡니다.

public bool Equals(object o)
{
    Point2 p = o as Point2;
    if (o != null)
        return this.X == o.X && this.Y == o.Y;
    else
        return false;
}

Equals Method는 구조적 평등을 사용하므로 필드를 기반으로 한 구현으로 gethashcode를 무시하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top