참조 유형에 대한 Equals()의 "가장 좋은" 정식 구현은 무엇입니까?

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

  •  09-06-2019
  •  | 
  •  

문제

참조 유형에 대해 Equals()를 구현하는 것은 생각보다 어렵습니다.현재 정식 구현은 다음과 같습니다.

public bool Equals( MyClass obj )
{
  // If both refer to the same reference they are equal.
  if( ReferenceEquals( obj, this ) )
    return true;

  // If the other object is null they are not equal because in C# this cannot be null.
  if( ReferenceEquals( obj, null ) )
   return false;

   // Compare data to evaluate equality    
   return _data.Equals( obj._data );
}

public override bool Equals( object obj )
{
  // If both refer to the same reference they are equal.
  if( ReferenceEquals( obj, this ) )
    return true;

  // If the other object is null or is of a different types the objects are not equal. 
  if( ReferenceEquals( obj, null ) || obj.GetType() != GetType() )
    return false;

  // Use type-safe equality comparison
  return Equals( (MyClass)obj );
}

public override int GetHashCode()
{
  // Use data's hash code as our hashcode  
  return _data.GetHashCode();
}

나는 이것이 모든 구석구석(상속 등)의 경우를 다루고 있다고 생각하지만 내가 틀렸을 수도 있습니다.여러분은 어떻게 생각하시나요?

도움이 되었습니까?

해결책

나는 이것에 대해 꽤 포괄적인 가이드를 얼마 전에 썼습니다.시작하려면 동등 구현을 공유해야 합니다(예:객체를 취하는 오버로드는 강력한 형식의 객체를 취하는 오버로드로 전달되어야 합니다.또한 GetHashCode를 재정의해야 하기 때문에 개체가 변경 불가능해야 한다는 등의 사항을 고려해야 합니다.자세한 내용은 여기를 참조하세요:

http://gregbeech.com/blog/implementing-object-equality-in-dotnet

다른 팁

this._data가 참조 유형이기도 하면 null이 아니기를 바라는 것이 좋습니다.

public bool Equals( MyClass obj )
{
    if (obj == null) {
        return false;
    }
    else {
        return (this._data != null && this._data.Equals( obj._data ))
                         || obj._data == null;
    }
}

public override bool Equals( object obj )
{
    if (obj == null || !(obj is MyClass)) {
        return false;
    }
    else {
        return this.Equals( (MyClass)obj );
    }
}

public override int GetHashCode() {
    return this._data == null ? 0 : this._data.GetHashCode();
}

상속에 관해서는 OO 패러다임이 마법을 발휘하도록 놔두는 것이 좋다고 생각합니다.

구체적으로, GetType() 검사를 제거해야 하며, 이로 인해 다형성이 중단될 수 있습니다.

나는 chakrit에 동의합니다. 서로 다른 유형의 객체가 동일한 데이터나 ID를 갖는 경우 의미상 동일하도록 허용되어야 합니다.

개인적으로 저는 다음을 사용합니다.

    public override bool Equals(object obj)
    {
        var other = obj as MyClass;
        if (other == null) return false;

        return this.data.Equals(other.data);
    }

값 유형을 작성하는지 참조 유형을 작성하는지에 따라 다릅니다.정렬 가능한 값 유형의 경우 다음을 권장합니다.프레임워크 디자인 지침을 준수하는 뼈대 값 유형을 구현하는 Visual Studio 2005용 코드 조각

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