2011-02-01 2 views
4

가능한 중복 :동등 연산자를 오버로드 할 때 null 값을 처리하는 가장 좋은 방법은 무엇입니까?

public class Effect 
{ 
    public static bool operator == (Effect a, Effect b) 
    { 
     return a.Equals (b); 
    } 

    public static bool operator != (Effect a, Effect b) 
    { 
     return !a.Equals (b); 
    } 

    public bool Equals (Effect effect) 
    { 
     return this.TypeID.Equals (effect.TypeID); 
    } 

    public override bool Equals (object obj) 
    { 
     return this.TypeID.Equals (((Effect) obj).TypeID); 
    } 
} 

null 값을 처리 할 수있는 가장 강력하고 가장 깨끗한 방법은 무엇입니까 :
How do I check for nulls in an ‘==’ operator overload without infinite recursion?

내가 이런 유형이 말?

현재 인스턴스 (this)와 전달 된 인스턴스 (effect/obj) 모두에 대해 null을 확인해야하는지 잘 모르겠습니다. 현재 인스턴스 (this)에 null이 있으면 컴파일러는 여전히 effect.Equals 또는 Object.Equals를 호출합니까?

또한 null 확인이 수행되어야하는 방법은 무엇입니까? Equals 메서드 내에서만 같다고 가정하고 평등 연산자 (==, !=)는 가정하지 않습니다.

+3

두 개체의 평등을 속성의 동일성으로 대체하는 것이 좋습니다. 구조체로 작업하는 것을 볼 수 있지만, 클래스에 대해 ==를 오버라이드하는 것은 모호한 버그의 교착 상태처럼 보입니다. –

+0

@djacobson,저기서 좋은 답변을 가져 주셔서 감사합니다. –

+0

나는 liho1eye와 동의하는 경향이 있습니다. 일반적으로 == 연산자가 오버로드되면 나쁜 소식입니다. 개인적으로 코드에서 직접 .Equals()를 호출하는 것이 익숙해지는 것이 더 나은 방법이라고 생각합니다. – Doug

답변

2

먼저 은 최소한 일 수 없으며 적어도 C# 컴파일러에서 생성 된 코드는 아닙니다.

둘째, 가능 ==의 오버로딩을 호출하지 않고 null 기준 확인 (또는 ((object) sometypeinstance) == null을 수행) 할 ReferenceEquals 방법을 사용한다.

+0

감사합니다.하지만 효과가 e = null 인 경우 "this"값이 null이되지 않습니까? –

+1

+1, 여기서 유일한 정답입니다. – nawfal

-1

이 추가 :

public static bool operator == (Effect a, Effect b)  
{ 
    return a is Effect && b is Effect && a.TypeID.Equals (b.TypeID);  
} 
public static bool operator != (Effect a, Effect b) 
{   
    return !(a == b);  
}  
public bool Equals (Effect effect)  
{   
    return this == effect);  
}  
public override bool Equals (object obj)  
{ 
    return obj is Effect && this == obj); 
} 

또는 대신 마지막 풋의 약

public static bool operator == (Effect a, Effect b)  
{ 
    return object.Equals(a, b); 
} 

Object.Equals의 기본 구현은()에 대한 검사는 null를 수행하는 방법

public override bool Equals (object obj)  
{ 
    if (obj == null) throw new ArgumentNullException(
     "obj", "obj is null"); 
    if (!(obj is effect)) throw new ArgumentException(
     "obj", "obj is not an effect"); 
    return obj is Effect && this == obj); 
} 
+1

그래도 조심하십시오. '=='는 당신이 또한'! ='를 정의 할 것을 요구합니다. 이로 인해 잠재적으로 상호 재귀가 발생할 수 있습니다. –

+1

해당 코드를 사용하는 경우! = 메서드에 해당하는 코드를 추가해야합니다. –

+0

죄송합니다. 완료되지 않았습니다 ... –

1

을 당신.

public static bool Equals(object objA, object objB) 
{ 
    return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB))); 
} 
+0

감사합니다. null 값을 사용했을 때, 내 타입이 널 참조 예외를 던졌습니다. –

+0

질문에 대한 의견보기 - ==와! =는 가볍게 수행 할 수있는 것이 아닙니다 :) – Doug

+0

감사합니다. 나는 당신의 메시지의 첫 부분에 관심을 기울이지 않았습니다. –

-1

예, 널 (null)에 프라하, 단한다 : 당신이 궁금 경우

, 여기 Object.Equals()는 그 (.NET 반사판의 호의를) 수행 방법입니다. 왜 그걸 두려워하니?

평소와 함께 놀 때 해시 코드 방법을 살펴 보는 것이 좋습니다. 그 두 가지 방법은 얽혀 있습니다.

0

클래스를 만드는 매개 변수를 사용하는 모든 메소드에서 null을 확인해야합니다. 피려

public class Effect 
{ 
    public static bool operator == (Effect a, Effect b) 
    { 
     if (a == null) && (b == null) return true; 
      if (a == null) return false; 
      return a.Equals (b); 
    } 

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

    public bool Equals (Effect effect) 
    { 
      if (b == null) return false; 
     return this.TypeID.Equals (effect.TypeID); 
    } 

    public override bool Equals (object obj) 
    { 
      if (obj == null) return false; 
     return this.TypeID.Equals (((Effect) obj).TypeID); 
    } 
} 

다른 것들이 평등이 구현되는 경우 구현해야 GetHashCode이다이 객체가 사전 또는 유사한에서 사용하려고하는 경우 GetHashCode는, 불변의 속성을 구현해야한다는 사실 해시 코드를 사용하여 항목을 비교하는 객체입니다.

+0

고마워, 이건 컴파일되지 않을거야, 그렇지? (return! a == b;)? –

+0

나의 실수 나는 한 쌍의 괄호를 놓쳤다. 나는 IDE의 버팀목에 너무 익숙해야한다. 나는 이것을 다음과 같이 바 꾸었습니다! (a == b); –

+0

Np man, 나는 IDE에 너무 많이 익숙하다 : O –

2

Visual Studio에는 기본 Equals() 구현을 제공하는 스 니펫이 있습니다. 네가 그렇게하지 않을 강한 이유가 없다면 나는 그것을 따를 것이다.

// override object.Equals 
public override bool Equals(object obj) 
{ 
    //  
    // See the full list of guidelines at 
    // http://go.microsoft.com/fwlink/?LinkID=85237 
    // and also the guidance for operator== at 
    // http://go.microsoft.com/fwlink/?LinkId=85238 
    // 

    if (obj == null || GetType() != obj.GetType()) 
    { 
     return false; 
    } 

    // TODO: write your implementation of Equals() here 
    throw new NotImplementedException(); 
    return base.Equals(obj); 
} 

// override object.GetHashCode 
public override int GetHashCode() 
{ 
    // TODO: write your implementation of GetHashCode() here 
    throw new NotImplementedException(); 
    return base.GetHashCode(); 
} 
+0

이 질문에 대답하지 않습니다. 그것을 수정하거나 삭제하십시오 .. – nawfal

+0

나는 그것이 질문에 대답한다고 믿습니다. "null 값을 처리하는 방법"이라는 질문에 대한 응답으로 스 니펫은 "return false"로 응답합니다. –

+0

가혹한 것에 대해 유감스럽게 생각합니다. 그러나 실수로, 연산자의 오버로딩에서 null 값을 처리 할 때 캐치가 발생합니다. OP가 당신이하는 일을 수행하더라도, 오버로드 된'=='또는'! ='내부에서 여전히 null 참조 예외를 제공 할 수 있습니다. – nawfal

관련 문제