문제

나는 다음 속성을 만들었습니다 InvalidCastException Getter가 언제 접근했을 때 ViewState[TOTAL_RECORD_COUNT] ~였다 null.

public long TotalRecordCount
{
    get { return (long)(ViewState[TOTAL_RECORD_COUNT] ?? -1); }
    set { ViewState[TOTAL_RECORD_COUNT] = value; }
}

내 생각은 오브젝트를 Unbox를 Unbox를 잘못 시도했다는 것입니다. ViewState[TOTAL_RECORD_COUNT] an int, 그것은 그것이 포함되어 있기 때문에 실패했습니다 long, 그러나 나는 그 논리에 결함이있을 수 있다고 생각합니다. 나는 그 결함을 지적하기 위해 독자에게 운동으로 남겨 둘 것입니다.

그 후 그 속성을 읽었습니다

public long TotalRecordCount
{
    get { return (long?)ViewState[TOTAL_RECORD_COUNT] ?? -1; }
    set { ViewState[TOTAL_RECORD_COUNT] = value; }
}

그것은 단지 부풀어 오른 것입니다. 그래도, 나는 원래 버전에 무엇이 잘못되었는지 궁금해하고 있습니다 ... 구조대에 stackoverflow?

실행하려는 경우에 유의하십시오 (long)(ViewState[TOTAL_RECORD_COUNT] ?? -1) 바로 즉시 오류 메시지가 나타납니다. Cannot unbox 'ViewState[TOTAL_RECORD_COUNT] ?? -1' as a 'long' 그리고 내가 실행한다면 (ViewState[TOTAL_RECORD_COUNT] ?? -1).GetType().Name 나는 얻다 Int32. 실행할 수 있습니다 (long)-1 그리고 -1로 끝납니다 Int64... 그래서 무슨 일이야?

도움이 되었습니까?

해결책

반환 유형 ViewState 인덱서입니다 Object (여기서 asp.net viewstate를 의미한다고 가정합니다). 이제 컴파일러가 이것을 볼 때 (코드와 동일)해야 할 일을 고려하십시오.

object o = ViewState[...];
var x = o ?? -1;

결과 유형의 표현식을 추론해야합니다 o ?? -1 어떻게든. 왼쪽에는 an이 봅니다 object, 오른쪽에는 an이 있습니다 int. 분명히이 표현의 가장 일반적인 유형은 또한 object. 그러나 이것은 실제로 그것을 사용하는 경우 -1 (왜냐하면 o null), 그것은 그것을 변환해야합니다 object - 그리고 int, 이것은 권투를 의미합니다.

그래서 x 유형입니다 object, 그리고 그것은 포함 할 수 있습니다 int (아마도 다른 적분 유형 - 우리는 당신의 뷰 스테이트에 무엇이 있는지 알지 못합니다. short, 예를 들어). 이제 당신은 다음을 씁니다.

long y = (long)x;

부터 x ~이다 object, 이것은 Unboxing입니다. 그러나 값 유형을 정확히 동일한 유형으로 만 Unbox value 유형 만 할 수 있습니다 (유일한 예외는 서명되지 않은 유형으로 서명 된 유형을 대체 할 수 있고 기본 기본 유형의 열거). 즉, 당신은 Unbox를 사용할 수 없습니다 int ~ 안으로 long. "추가"코드가 없으면 이것을 재현하는 훨씬 간단한 방법은 다음과 같습니다.

object x = 123;
long y = (long)x;

또한 던지는 것 InvalidCastException, 그리고 똑같은 이유로.

다른 팁

캐스트는 한 단계 만 있어야합니다.

표현식 <object> ?? <int> 다른 객체를 생성하고 첫 번째 값이 NULL 일 때, 즉. ViewState[TOTAL_RECORD_COUNT] NULL이면 결과 값은 객체가되고 박스형 int32가 있습니다.

int32를 포함하는 객체를 긴 상자에 넣을 수는 없으므로 먼저 INT32로 Unbox를 Unbox를 Unpobine 다음 오랫동안 캐스팅해야합니다.

문제는 ViewState[TOTAL_RECORD_COUNT], 문제는 -1의 권투 및 개봉입니다.

   ViewState[TOTAL_RECORD_COUNT] ?? -1

당신은 사용하고 있습니까 ?? "Object"및 "Int"의 연산자. 결과 유형은 "개체"입니다. 이는 필드가 뷰 상태에 존재하지 않을 때 -1이 박스형 (int)을 의미합니다.

그런 다음 프로그램이 나중에 (int) -1을 Unbox를 길게하려고 할 때 나중에 충돌합니다.

원본에서, 당신이 그것을 분해한다면, 당신은 다음을하고있었습니다.

(ViewState[TOTAL_RECORD_COUNT] ?? -1)

그만큼 Null-Coalescing 연산자 (??) 구체적으로 설계되었습니다.

a의 기본값을 정의합니다 무효 값 유형 만큼 잘 참조 유형.

귀하의 경우, 시스템을 처리하는 데 사용하여 "-1"을 가져 와서 INT32로 취급하고 새 System.Object로 상자를 가져옵니다. 그런 다음 캐스트가 단일 단계에서 유형을 변경할 수없고 유형을 변경할 수 없기 때문에 int32를 길이로 Unbox를 Unbox로 Unbox로 연결하려고합니다.

L 접미사를 사용하여 -1이 길다는 것을 지정하여이를 쉽게 해결할 수 있습니다.

public long TotalRecordCount
{
    get { return (long)(ViewState[TOTAL_RECORD_COUNT] ?? -1L); }
    set { ViewState[TOTAL_RECORD_COUNT] = value; }
}

int64 값 유형이므로 캐스팅입니다 null 값 유형에 항상 예외가 발생합니다 (NullReferenceException). int32를 Int64에 캐스팅하면 성공할 수 있으며 InvalidCastException.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top