2012-03-16 2 views
12

Microsoft Access 데이터베이스의 데이터를 MS SQL Server 데이터베이스에 보관하는 코드가 있습니다. Access 테이블에서 이미 채워진 데이터 판독기가 있고 삽입을 준비하기 위해 SqlCommand에 매개 변수를 추가한다고 가정 할 경우 우리는 실패한 타입 변환을 가지고 있습니다. 다음은 코드입니다.왜 short에서 int로 캐스트가 실패합니까?

oSqlServerDbCmd_ForInsert.Parameters.AddWithValue("@Duration", 
    (int) oReader["Duration"]); 

oReader의 필드는 실제로 Access Integer이며 C#의 줄임말입니다. 여기에 짧은 값으로 캐스트하면 아무런 문제가 없습니다. 그러나 우리가 int로 형변환하면 코드는 InvalidCastException을 던집니다. MSDN documentation에서 이것을 잘못 읽었을 수 있습니다.

"short에서 int, long, float, double 또는 decimal 사이의 미리 정의 된 암시 적 변환이 있습니다."

...하지만 작동해야합니다 (내 추론, 암시 적 변환이 정의 된 경우 왜 명시 적 유형 변환이 작동하지 않을까요?). AddWithValue가 객체를 받아들이 기 때문에 캐스트가 필요 없기 때문에 코드에서 캐스트를 실제로 제거 했으므로이 캐스트가 실패한 이유에 대한 설명을보고 싶습니다. 미래.

+1

좋은 글이 http://blogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx –

+0

이에 대한 답변하지 않습니다 당신의 질문,하지만 당신의'@ Duration' 매개 변수에는 숫자 형 데이터 타입인데,이 경우'AddWithValue' 호출에서 문자열 값을 사용하고 싶지 않을 것입니다. – phoog

+0

@phoog 나는이 질문이 정말로 끝나기를 바라는 것과 혼란 스럽기 때문에 그 변환을 제거하기 위해 코드를 편집했다. 간단한 대답은 문자열 변환이 우리가 상속 받았을 때 코드에 있었기 때문입니다. 소스 DB에서 데이터 유형을 변경하기 전까지는 코드를 조사 할 필요가 없었습니다. 일단 그것이 깨지고 우리가 파고 들자면 문자열 변환이 불필요하다는 것을 알았습니다 (문제는 아니지만 믿거 나 말거나). –

답변

18

손에 가지고있는 것은 unboxing의 인스턴스입니다. 특히 박스 처리를 해제 할 때 원래 상자에 담긴 값의 유형에만 unbox 할 수 있습니다. 해당 유형이 A이고 B로 언 박싱하는 경우 A에서 B 로의 암시 적 변환이 존재하는지 상관하지 않습니다. (여전히 언 박싱은 실패합니다).

Eric Lippert의 classic blog post에서 관련 설명을 참조하십시오. 당신이 개봉기 때문에

+0

+1 항상 잊고 있습니다. 'object o = (short) 10; int i = (int) o;'실패합니다. –

+1

아, 그 말이 맞습니다. 그래서, 제가 처음에는 짧은 것으로 캐스팅했는데, 문제없이 int로 캐스팅 할 수 있었습니까? –

+1

@ awilson53 : 정확합니다. – Jon

5

당신은 매우 구체적인 형식으로 캐스팅 할 필요 - 문제가 oReader["Duration"]object 인스턴스를 반환하는 것입니다 :

short myShort = 42; 
object o = myShort; 
int myInt = (int)o; //fails 

그것은 당신이 다음 int로, 짧은 첫 번째로 다시 캐스팅 성공할 것이다 :

(int) (short) oReader["Duration"] 
에릭 Lippert의에서
+0

의견을 보내 주셔서 감사합니다. +1 ... 두 사람 모두 내 질문에 대답하여 첫 번째 발동기와 함께 가야합니다. –