2009-05-21 3 views
4

상황에 대한 몇 가지 코드 :C#을 암시 적 변환 및 == 연산자

class a 
{ 

} 

class b 
{ 
    public a a{get;set;} 
    public static implicit operator a(b b) 
    { 
     return b.a; 
    } 
} 

    a a=null; 
    b b=null; 
    a = b; 

    //compiler: cannot apply operator '==' to operands of type tralala... 
    bool c = a == b; 

이 하나가 암시 적으로 서로 변환 할 수있는 다른 종류의 인스턴스에 == 연산자를 사용할 수 있습니까? 내가 놓친 게 무엇입니까?

편집 :
유형이 동일한 통화 ==, 왜

int a=1; 
double b=1; 
bool c=a==b; 

일을해야하는 경우?

+1

값 유형 및 참조 유형이 아니기 때문에 int/double 예제가 작동한다고 가정합니다 ... –

+1

그럴 수 있습니다. 문제가있는 경우에만 참조 유형이 값 유형처럼 암시 적으로 변환을 수행 할 수없는 이유를 설명하지 않습니다. –

답변

12

implicit 연산자는 할당에 대해서만 작동합니다.

당신은 같은 항등 (==) 연산자를 오버로드 할 :

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

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

class b 
{ 
    public a a{get;set;} 
    public static implicit operator a(b b) 
    { 
     return b.a; 
    } 
} 

이 다음 게시물에 제안 두 종류 a의 객체와 b을 비교할 수 있도록해야합니다.

var x = new a(); 
var y = new b(); 
bool c = (x == y); // compiles 

참고 :

컴파일러는 경고로 나는 단순히 GetHashCodeEquals 메서드를 재정의 recommmend,하지만 당신이 그들을이 표시되지 않도록 할 것, 당신이로이 따른다고 할 수 있습니다.

변경에 a의 클래스 선언 :

#pragma warning disable 0660, 0661 
class a 
#pragma warning restore 0660, 0661 
{ 
    // ... 
} 
+0

및 이 경우 a == b 표현식은 문제없이 컴파일됩니다. – Galilyou

+0

이것은 정답처럼 보입니다. 이것도 알아 냈어. 오직 - 나는이 연산자 오버로딩이 과잉이라고 생각한다. (gethash()와 equals() function overloading을 요구한다.) –

+0

예, 사용자 정의 유형에서 사용자 정의 (오버로드 된) 연산자를 정의하거나 사용하는 데 제한이 없습니다. – Noldorin

0

사용하여 각각의 경우에서이

bool c = a.Equals(b); 
+0

이것은 특별한 경우에 유용하지 않습니다. 왜냐하면 나는 lambdas와 builder 패턴을 다음과 같이 동적 속성 설정자를 남용하여 남용하고 있습니다. factory.Object.With (object => object.MyProp == newPropValue) .Create() –

1

나는 당신이 실제로 당신이 관심있는 유형 == 연산자를 재정의해야하는 컴파일/런타임이 여전히 경우에도 불평 여부 상상에 맡기겠습니다. 유형은 암시 적 변환이 가능하므로 실험해야 할 것입니다.

public static bool operator ==(a a, b b) 
    { 
     //Need this check or we can't do obj == null in our Equals implementation 
     if (((Object)a) == null) 
     { 
      return false; 
     } 
     else 
     { 
      return a.Equals(b); 
     } 
    } 

또는 ole6ka가 제안하는 것과 같은 Equals 구현을 사용하고 구현시 필요한 유형 캐스팅을 수행하는지 확인하십시오.

9

그것은 하나 암시 적으로 서로 변환 할 수 있습니다 다른 유형의 인스턴스에 == 연산자를 사용할 수 있습니까?

예.

나는 무엇을 놓쳤는가?

다음은 사양의 관련 부분입니다. 당신은 강조된 단어를 놓쳤습니다.

미리 정의 된 기준 입력 항등 연산자는 두 피연산자 가 레퍼런스 값을 입력하거나 널 문자들은 [있음] 요구한다. 또한, 표준 유형의 피연산자 유형에서 다른 피연산자 유형 유형으로 암시 적 변환이 존재합니다.

사용자 정의 변환은 표준 변환이 아닙니다. 이들은 참조 유형입니다. 따라서 사전 정의 된 참조 유형 항등 연산자는 후보가 아닙니다.

형식이 동일한 호출 ==, 이어야하는 경우 [double == int]가 작동하는 이유는 무엇입니까?

유형이 동일해야한다는 가정이 잘못되었습니다. int에서 double 로의 표준 암시 적 변환이 있으며 두 개의 double을 취하는 항등 연산자가 있으므로이 방법이 유용합니다.

그것은 컴파일 - 서로 다른 것으로 알려진 두 개의 참조를 비교하기 위해 미리 정의 된 참조 유형 평등을 연산자를 사용하면 컴파일 타임 오류는 다음과 같습니다

나는 당신이이 비트를 놓친 생각 시각. 두 피연산자는 동일한 를 참조하기 위해, 예를 들어, 피연산자 컴파일시 타입 두 클래스 타입 A 및 B, 그리고 만약 있지도가없고 B는 다른 파생 경우, 그것은 불가능하다 목적. 따라서 컴파일 타임 오류로 간주되는 작업은 입니다.

+0

이 문제를 해결해 주셔서 감사합니다. –