Program Tip

정수를 십진수로 풀 수없는 이유는 무엇입니까?

programtip 2020. 12. 4. 20:19
반응형

정수를 십진수로 풀 수없는 이유는 무엇입니까?


나는 한 IDataRecord reader나는 다음과 같이에서 소수를 검색하는거야 것을 :

decimal d = (decimal)reader[0];

어떤 이유로 "지정된 캐스트가 유효하지 않습니다"라는 잘못된 캐스트 예외가 발생합니다.

내가 할 때 reader[0].GetType()그것이 Int32라고 알려줍니다. 내가 아는 한, 이것은 문제가되지 않는다 ....

나는 잘 작동하는이 스 니펫으로 이것을 테스트했습니다.

int i = 3750;
decimal d = (decimal)i;

이로 인해 독자에 포함 된 정수를 십진수로 풀지 못하는 이유가 궁금해졌습니다.

왜 이런 일이 발생하는지 아는 사람이 있습니까? 내가 놓친 미묘한 것이 있습니까?


값 형식을 원래 형식 (및 해당 형식의 null 허용 버전)으로 만 풀 수 있습니다.

그건 그렇고, 이것은 유효합니다 (두 줄 버전의 속기).

object i = 4;
decimal d = (decimal)(int)i; // works even w/o decimal as it's a widening conversion

이 뒤에있는 이유는 Eric Lippert의 블로그 항목 : Representation and Identity

개인적으로 캐스트 구문으로 수행되는 작업을 네 가지 유형의 작업으로 분류합니다 (모두 다른 IL 명령이 있음).

  1. Boxing ( boxIL 명령) 및 unboxing ( unboxIL 명령)
  2. 상속 계층 구조를 통한 캐스팅 ( dynamic_cast<Type>C ++에서 와 같이 castclassIL 명령어를 사용하여 확인)
  3. 기본 유형 간 캐스트 ( static_cast<Type>C ++에서 와 같이 기본 유형간에 다양한 유형의 캐스트에 대한 많은 IL 명령어가 있음)
  4. 사용자 정의 변환 연산자 호출 (IL 수준에서는 적절한 op_XXX메서드 에 대한 메서드 호출 일뿐입니다 ).

로 캐스팅하는 int문제가 없지만 decimal개체를 개봉 할 때 개체에 포함 된 정확한 유형을 사용해야합니다.

언 박싱하기 위해 int에 값을 decimal값, 당신은 먼저 진수에 캐스팅, int로서 언 박싱 :

decimal d = (decimal)(int)reader[0];

IDataRecord 인터페이스에는 값을 unboxing하는 메서드도 있습니다.

decimal d = (decimal)reader.GetInt32(0);

여기에 간단한 해결책이 있습니다. unboxing을 처리 한 다음 10 진수로 캐스팅합니다. 나를 위해 잘 작동했습니다.

decimal d = Convert.ToDecimal(reader[0]);  // reader[0] is int

Mehrdad Afshari는 다음과 같이 말했습니다.

값 형식을 원래 형식 (및 해당 형식의 null 허용 버전)으로 만 풀 수 있습니다.

깨달아야 할 것은 캐스팅과 언 박싱 사이에 차이 가 있다는 것입니다 . jerryjvl은 훌륭한 발언을했습니다

어떤 의미에서 언 박싱과 캐스팅은 매우 다른 작업이기 때문에 구문 적으로 동일하게 보이는 것은 부끄러운 일입니다.

주조:

int i = 3750; // Declares a normal int
decimal d = (decimal)i; // Casts an int into a decimal > OK

권투 / 개봉 :

object i = 3750; // Boxes an int ("3750" is similar to "(int)3750")
decimal d = (decimal)i; // Unboxes the boxed int into a decimal > KO, can only unbox it into a int or int?

참고 URL : https://stackoverflow.com/questions/1085097/why-cant-i-unbox-an-int-as-a-decimal

반응형