2011-12-15 3 views
2

과부하 연산자, 특히 암시 적 및 명시 적 변환과 관련된 광범위한 작업을 한 적이 없습니다.숫자 형식 및 예기치 않은 결과가있는 명시 적 및 암시 적 연산자

그러나 자주 사용되는 여러 개의 숫자 매개 변수가 있으므로 구조체를 숫자 형식 주위에 래퍼로 ​​만들어 이러한 매개 변수를 강력하게 입력합니다.

public struct Parameter 
{ 
    private Byte _value; 
    public Byte Value { get { return _value; } } 

    public Parameter(Byte value) 
    { 
     _value = value; 
    } 

    // other methods (GetHashCode, Equals, ToString, etc) 

    public static implicit operator Byte(Parameter value) 
    { 
     return value._value; 
    } 
    public static implicit operator Parameter(Byte value) 
    { 
     return new Parameter(value); 
    } 

    public static explicit operator Int16(Parameter value) 
    { 
     return value._value; 
    } 
    public static explicit operator Parameter(Int16 value) 
    { 
     return new Parameter((Byte)value); 
    } 
} 

내가 명시 적 및 암시 사업자의 묘리를 터득하기 위해 내 테스트 구현과 실험되면서, 나는 명시 적으로 내 Parameter 유형과는 포기하지 않았다 내 놀라지에 Int64 캐스팅하려고 예를 들면 다음과 같습니다 구현입니다 예외 및 더 놀라운 것은 숫자를 잘라 버렸습니다. 나는 사용자 지정 명시 적 연산자를 제외하고 시도했지만 여전히 동일하게 동작합니다.

public void TestCast() 
{ 
    try 
    { 
     var i = 12000000146; 
     var p = (Parameter)i; 
     var d = (Double)p; 

     Console.WriteLine(i); //Writes 12000000146 
     Console.WriteLine(p); //Writes 146 
     Console.WriteLine(d); //Writes 146 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.Message); //Code not reached 
    } 
} 

그래서 난 내 구조체 대신에 일반 Byte 내 실험을 반복하고 같은 정확한 동작을 가지고, 그래서 분명히이 예상되는 동작,하지만 난 던질 것 데이터를 잃게 결과 명시 적 캐스트를 생각 예외.

+0

아니, 명시 적 캐스트 정보를 잃을 수 있습니다. 묵시적인 캐스트는해서는 안됩니다. –

+0

'AnyCPU','x32' 또는'x64'로 컴파일 중입니까? – ja72

+0

@ ja72 응답 지연으로 미안하지만, x86으로 컴파일 중입니다. – psubsee2003

답변

7

컴파일러가 변환의 "양쪽"(또는 둘 다)에 명시 내장 넣어 변환시킨다 명시 사용자 정의 전환 분석하면. 따라서 예를 들어, 당신은 프레드에 INT에서 사용자 정의 변환이있는 경우, 당신은이 :

int? x = whatever; 
Fred f = (Fred)x; 

다음 "프레드에 INT에서 명시 적 변환 컴파일러 이유가, 그래서 명시 적으로 만들 수 있습니다 int에서 int로 변환 한 다음 int를 Fred로 변환하십시오.

예제에서 long에서 short 로의 명시 적 변환이 내장되어 있으며 short에서 Parameter 로의 사용자 정의 명시 적 변환이 있으므로 매개 변수를 long으로 변환하는 것이 적합합니다.

암시 적 변환에 대해서도 마찬가지이며 컴파일러에서 e에 내장 된 암시 적 변환을 삽입 할 수 있습니다 사용자 정의 암시 적 변환의 반대쪽

컴파일러는 사용자 정의 개의 체인을 연결하지 않습니다.

명시 적 변환을 올바르게 작성하는 것은 C#에서는 어려운 작업이므로 변환을 다루는 사양의 전체 장을 철저하고 깊이있게 이해할 때까지 시도하지 않는 것이 좋습니다.체인 변환의 몇 가지 흥미로운 측면에 대한

는 주제에 내 문서를 참조하십시오

http://blogs.msdn.com/b/ericlippert/archive/2007/04/16/chained-user-defined-explicit-conversions-in-c.aspx

http://blogs.msdn.com/b/ericlippert/archive/2007/04/18/chained-user-defined-explicit-conversions-in-c-part-two.aspx

+0

설명 및 블로그 링크를 제공해 주셔서 감사합니다. 이전 게시물 중 일부를 놓친 적이있어서 매우 유익했습니다. 제가 작업하고있는 프로젝트는 일종의 애완 동물 프로젝트로, 실제 직장에서 도와주기 위해 새로운면을 실험하기 위해 많은 양을 사용하고 있습니다. 따라서 암묵적/암묵적 전환은 우리가했던 것처럼 많은 실험이었습니다. – psubsee2003

+0

이제 블로그를 읽었으므로 사용자 지정 명시 적 및 암시 적 변환을 수행하는 함정을 이해하고 있다고 생각합니다. 귀하의 대답에서, 나는 거기에 명시 적으로 변환 사이의 긴 및 바이트, 컴파일러는 해당 변환을 메서드 호출에 매개 변수를 긴 바이트로 변환 할 삽입됩니다. 그리고 long에서 byte 로의 캐스트는 long에서 최하위 8 비트를 취할 것이므로, 나는 Parameter에 할당 된 값으로 146을 남겨 둡니다. 완전한 이해가됩니다. 고마워요. – psubsee2003

3

이 목표 :

public static implicit operator Byte(Parameter value) 
{ 
    return value._value; 
} 
public static implicit operator Parameter(Byte value) 
{ 
    return new Parameter(value); 
} 

가에 위치 :

그래서 난 강력하게 이러한 매개 변수

그리고이 코드를 입력 할 수있는 숫자 유형의 래퍼로 구조체를 만드는 오전 총 모순. 양방향 암시 적 연산자를 추가하면 래퍼가 가져올 수있는 모든 유형 안전이 무효화됩니다.

암시 적 변환을 삭제하십시오. 그것들을 명시 적으로 변경할 수 있습니다.

+0

@ Hank 내가 찾고있는 유형 안전성에 대한 설명이 충분히 명확하지 않았습니다. 여러 매개 변수 유형 (매개 변수 1, 매개 변수 2 등)이 있습니다. 내가 찾고 있던 타입 안전은 실수로 누군가 Parameter2를 찾고있는 메소드에서 Parameter1을 사용하는 것을 방지합니다. 그러나 귀하의 요점은 상관없이 이해할 수 있으므로 암묵적인 운영자 접근법을 다시 생각해 보겠습니다. – psubsee2003

관련 문제