int를 소수점으로 Unbox를 Unbox 할 수없는 이유는 무엇입니까?
문제
나는있다 IDataRecord reader
다음과 같이 소수점을 검색하고 있습니다.
decimal d = (decimal)reader[0];
어떤 이유로 든 이것은 "지정된 캐스트가 유효하지 않음"을 말하는 유효하지 않은 캐스트 예외를 던집니다.
내가 할 때 reader[0].GetType()
그것은 그것이 int32라는 것을 알려줍니다. 내가 아는 한, 이것은 문제가되지 않아야합니다 ....
나는 잘 작동하는이 스 니펫으로 이것을 테스트했습니다.
int i = 3750;
decimal d = (decimal)i;
이로 인해 독자에게 포함 된 int가 소수점으로 포함되지 않은 이유를 궁금해하여 머리를 긁어 냈습니다.
왜 이것이 왜 발생했는지 아는 사람이 있습니까? 내가 놓친 미묘한 것이 있습니까?
해결책
값 유형을 원래 유형 (및 해당 유형의 무효 버전)으로 만 허스받을 수 있습니다.
그건 그렇고, 이것은 유효합니다 (두 줄 버전의 속도 만) :
object i = 4;
decimal d = (decimal)(int)i; // works even w/o decimal as it's a widening conversion
이것의 이유 때문에 이것을 읽으십시오 Eric Lippert의 블로그 항목 : 표현 및 정체성
개인적으로 Cast Syntax로 수행 한 작업을 네 가지 유형의 작업으로 분류합니다 (모두 다른 IL 지침이 있습니다).
- 권투 (
box
IL 명령어) 및 Unboxing (unbox
IL 교육) - 억제 계층을 통해 캐스팅 (예 :
dynamic_cast<Type>
C ++에서 사용됩니다castclass
확인을위한 IL 명령) - 원시 유형 사이의 주조 (예 :
static_cast<Type>
C ++에는 원시 유형 사이에 다른 유형의 캐스트에 대한 많은 IL 지침이 있습니다) - 사용자 정의 변환 연산자 호출 (IL 레벨에서는 적절한 방법으로 메소드 호출 일뿐입니다.
op_XXX
방법).
다른 팁
캐스팅에 문제가 없습니다 int
에게 decimal
, 그러나 객체를 무너 뜨릴 때 객체에 포함 된 정확한 유형을 사용해야합니다.
Unbox int
a 로의 가치 decimal
값, 먼저 int로 Unbox를 Unbox로 발사 한 다음 10 진수로 캐스팅합니다.
decimal d = (decimal)(int)reader[0];
IdatareCord 인터페이스에는 값을 무너 뜨리는 방법도 있습니다.
decimal d = (decimal)reader.GetInt32(0);
간단한 솔루션이 있습니다. Unboxing을 처리 한 다음 소수점으로 캐스팅됩니다. 나를 위해 잘 일했습니다.
decimal d = Convert.ToDecimal(reader[0]); // reader[0] is int
Mehrdad Afshari는 다음과 같이 말했습니다.
값 유형을 원래 유형 (및 해당 유형의 무효 버전)으로 만 허스받을 수 있습니다.
깨달아야 할 것은 그 것입니다 캐스팅과 Unboxing에는 차이가 있습니다. Jerryjvl은 훌륭한 발언을했습니다
어떤 의미에서는 Unboxing과 캐스팅이 매우 다른 작업이기 때문에 구문 적으로 동일하게 보이는 것은 부끄러운 일입니다.
주조:
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?