Equals() 및 연산자== 재로드 지침(C# 프로그래밍 안내서)

17854 단어 equals()
C#에는 참조가 동일하고 값이 동일하다는 두 가지 차이점이 있습니다.값이 같다는 것은 모두가 보편적으로 이해하는 의미에서 같다. 이것은 두 대상이 같은 값을 포함한다는 것을 의미한다.예를 들어 두 값이 2인 정수는 값이 같다.인용이 같다는 것은 두 대상이 아니라 두 대상이 인용한다는 것을 의미한다. 이 두 대상이 인용한 것은 같은 대상이다.다음 예와 같이 간단한 지정을 통해 수행할 수 있습니다.

  
System.Object a = new System.Object();
System.Object b
= a;
System.Object.ReferenceEquals(a, b);
// returns true

위의 코드에는 한 개의 대상만 존재하지만, 이 대상에 대한 여러 개의 인용이 있습니다: a와 b.그것들은 같은 대상을 인용하기 때문에 인용의 상등성을 가지고 있다.만약 두 대상이 인용의 상등성을 가지고 있다면 그것들도 값의 상등성을 가지지만 값의 상등성은 인용의 상등성을 보장할 수 없다.
인용의 상등성을 검사하려면 ReferenceEquals을 사용해야 한다.값의 상등성을 검사하려면 Equals 또는 Equals를 사용해야 한다.
Equals 다시 쓰기
Equals는 모든 종류가 다시 쓰기를 허용하는 허위 방법이다.값(본질적으로 모든 값 유형일 수 있음)이나 복수 클래스와 같은 값 세트를 나타내는 모든 클래스는 Equals를 다시 써야 합니다.유형IComparable을 구현하려면 Equals를 다시 써야 합니다.
Equals의 새로운 구현은 Equals의 모든 보증을 따라야 한다.
  • x.Equals(x)가true로 돌아갑니다.
  • x.Equals(y)와 y.Equals(x)가 같은 값을 되돌려줍니다.
  • (x.Equals(y) & y.Equals(z))가true로 돌아오면 x.Equals(z)가true로 돌아갑니다.
  • x와 y가 인용한 대상을 수정하지 않으면 x.Equals(y)의 후속 호출은 같은 값을 되돌려줍니다.
  • x.Equals(null)가false로 되돌아옵니다.

  • Equals의 새로운 실현은 이상을 일으켜서는 안 된다.Equals의 모든 종류를 다시 쓰는 것을 권장합니다. System.Object.GetHashCodeEquals(대상)를 실현하는 것 외에 모든 클래스가 자신의 유형에 대해 Equals(유형)를 실현하여 성능을 향상시키는 것을 권장합니다.예를 들면 다음과 같습니다.
     
    
       
    class TwoDPoint : System.Object
    {
    public readonly int x, y;

    public TwoDPoint( int x, int y) // constructor
    {
    this .x = x;
    this .y = y;
    }

    public override bool Equals(System.Object obj)
    {
    // If parameter is null return false.
    if (obj == null )
    {
    return false ;
    }

    // If parameter cannot be cast to Point return false.
    TwoDPoint p = obj as TwoDPoint;
    if ((System.Object)p == null )
    {
    return false ;
    }

    // Return true if the fields match:
    return (x == p.x) && (y == p.y);
    }

    public bool Equals(TwoDPoint p)
    {
    // If parameter is null return false:
    if (( object )p == null )
    {
    return false ;
    }

    // Return true if the fields match:
    return (x == p.x) && (y == p.y);
    }

    public override int GetHashCode()
    {
    return x ^ y;
    }
    }

    베이스 클래스를 호출할 수 있는 Equals의 모든 파생 클래스는 비교를 완료하기 전에 이렇게 해야 합니다.다음 예에서 Equals는 빈 매개변수를 검사하고 파생 클래스의 유형과 비교하는 기본 클래스 Equals를 호출합니다.이렇게 하면 파생 클래스에 표시된 새로운 데이터 필드를 검사하는 작업은 파생 클래스의 Equals에 남겨집니다.
     
    
       
    class ThreeDPoint : TwoDPoint
    {
    public readonly int z;

    public ThreeDPoint( int x, int y, int z)
    :
    base (x, y)
    {
    this .z = z;
    }

    public override bool Equals(System.Object obj)
    {
    // If parameter cannot be cast to ThreeDPoint return false:
    ThreeDPoint p = obj as ThreeDPoint;
    if (( object )p == null )
    {
    return false ;
    }

    // Return true if the fields match:
    return base .Equals(obj) && z == p.z;
    }

    public bool Equals(ThreeDPoint p)
    {
    // Return true if the fields match:
    return base .Equals((TwoDPoint)p) && z == p.z;
    }

    public override int GetHashCode()
    {
    return base .GetHashCode() ^ z;
    }
    }

    Overriding Operator ==
    기본적으로 연산자==는 두 인용이 같은 대상을 지시하는지 판단함으로써 인용이 같은지 테스트하기 때문에 인용 유형은 연산자==를 실현하지 않아도 이 기능을 얻을 수 있다.유형이 변경되지 않을 때는 인스턴스에 포함된 데이터가 변경될 수 없다는 의미로, 연산자==를 다시 로드하여 비교 참조가 같은지 아닌지를 비교하는 것이 아니라 값이 같은지 비교하는 것이 유용할 수 있습니다. 왜냐하면 변하지 않는 대상으로서 값이 같으면 같은 것으로 간주할 수 있기 때문입니다.비변수 유형에서 연산자 ==을 다시 쓰지 않는 것을 권장합니다.
    다시 불러오는 연산자 = 이상을 일으켜서는 안 된다.연산자==의 모든 유형에 대해 연산자!=를 다시 로드해야 합니다.예를 들면 다음과 같습니다.
     
    
       
    // add this code to class ThreeDPoint as defined previously
    //
    public static bool operator == (ThreeDPoint a, ThreeDPoint b)
    {
    // If both are null, or both are same instance, return true.
    if (System.Object.ReferenceEquals(a, b))
    {
    return true ;
    }

    // If one is null, but not both, return false.
    if ((( object )a == null ) || (( object )b == null ))
    {
    return false ;
    }

    // Return true if the fields match:
    return a.x == b.x && a.y == b.y && a.z == b.z;
    }

    public static bool operator != (ThreeDPoint a, ThreeDPoint b)
    {
    return ! (a == b);
    }

     
    참고: ----------------------
    연산자==의 재부팅에서 흔히 볼 수 있는 오류는 인용의 상등성을 검사하기 위해 (a=b), (a==null) 또는 (b==null)를 사용하는 것이다.이것은 다시 불러오는 연산자 = 을 호출하여 무한 순환을 초래할 수 있습니다.Reference Equals를 사용하거나 유형을 강제로 Object로 변환하여 무한 순환을 피해야 합니다.
    ------------------------------

    좋은 웹페이지 즐겨찾기