質問

私はInvalidCastExceptionViewState[TOTAL_RECORD_COUNT]たときにゲッターがアクセスされた場合nullを投げた次のプロパティを作成します。

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

私の考えは、それは間違ってそれがViewState[TOTAL_RECORD_COUNT]が含まれているため失敗したintlong内のオブジェクトをVHS版しようとしたことですが、私はそのロジックに欠陥があるかもしれないと思います。私はその欠陥を指摘する読者への課題として、それを残してます。

私は以来、プロパティは読み取りにすることを変更しました。

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インデクサの戻り値の型は(私はあなたがここにASP.NETのビューステートを意味すると仮定)Objectです。今コンパイラが、それは(あなたのコードに相当する)これを見ているときに実行しているかを検討します:

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

これは、何らかの形で表現o ?? -1の結果の型を推論する必要があります。それはobjectを見て左側には、右側にintです。明らかに、この表現のための最も一般的なタイプもobjectです。しかし、これは(-1がNULLであったため)、それが実際にそのoを使って終了した場合、それはobjectに変換しなければならないことを意味します - 。とintのために、これはボクシングを意味します。

だから、xはタイプobjectのものであり、それはintが含まれていてもよい(そしておそらくまた、いくつかの他の整数型 - 私たちはあなたのビューステートにあるかわからない、それは例えば、shortすることができます)。今、あなたは書きます:

long y = (long)x;
xobjectあるので

、これはアンボクシングされます。ただし、缶(あなたは、その下地の種類のための符号付き等価unsigned型の型、および列挙を置き換えることができることのみを除いて)全く同じタイプにのみVHS版値型。それはあなたがintlongをUnboxのことはできません。これをREPROするはるかに簡単な方法は、ない「余分な」コードで、次のようになります。

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

またInvalidCastExceptionをスローし、まったく同じ理由でます。

他のヒント

キャストは1つのステップのみである必要があります。

、すなわち、発現<object> ?? <int>は、別のオブジェクトを生成し、最初の値がヌルである場合。 ViewState[TOTAL_RECORD_COUNT]がnullである場合、結果の値は、それに箱入りのInt32と、オブジェクトになります。

あなたが長いののInt32を含むオブジェクトをVHS版はできませんので、

は、最初のInt32にそれをUnboxの、そして長いにキャストする必要があります。

問題は、問題が-1のボクシングとアンボクシングされ、ViewState[TOTAL_RECORD_COUNT]のアンボクシングではありません。

   ViewState[TOTAL_RECORD_COUNT] ?? -1

あなたは使用しています? 「オブジェクト」と「INT」のオペレーター。得られたタイプが「オブジェクト」です。このフィールドは、ビューステートに存在しない場合に-1を(intとして)ボックス化されることを意味します。

それは(int)をVHS版しようとすると、

次に、あなたのプログラムは、後にクラッシュ-1限ります。

あなたはそれを打破する場合は、あなたの元には、あなたがやっていた。

(ViewState[TOTAL_RECORD_COUNT] ?? -1)

ヌル合体演算子(??)specifiallyあるの設計されます:

  

null許容値型のと同様の参照型のデフォルト値を定義する。

あなたのケースでは、あなたがたSystem.Objectを処理するためにそれを使用しているので、あなたの「-1」を取るのInt32として扱い、そして新しいのSystem.Objectにそれを箱になるだろう。キャストは、単一のステップで種類をVHS版と変更することはできませんので、次に、それは、失敗した、長いへのInt32をVHS版しようとします。

あなたは-1がLの接尾辞を使用しての長さであることを指定することで、簡単にこの問題を解決することができます:

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

のInt64 のようnullを鋳造、値型であります値型に常に例外(NullReferenceException)をスローします。そして、Int64型へのInt32をキャストすることは成功するとInvalidCastExceptionをスローしません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top