8

私はこれを理解するのに苦労しています。次の例を考えてみましょう。

protected void Page_Load(object sender, EventArgs e)
{
    // No surprise that this works
    Int16 firstTest = Convert.ToInt16(0);
    int firstTest2 = (int)firstTest;

    // This also works
    object secondTest = 0;
    int secondTest2 = (int)secondTest;

    // But this fails!
    object thirdTest = Convert.ToInt16(0);
    int thirdtest2 = (int)thirdTest;  // It blows up on this line.
}

実行時に発生する特定のエラーは、Visual StudioでSpecified cast is not valid. QuickWatchを実行すると、値が。になります。(int)thirdTestCannot unbox 'thirdTest' as a 'int'

ここで一体何が起こっているのですか?

4

3 に答える 3

12

開梱は、ドキュメントで説明されているように正確なタイプをチェックします。

アンボックス化とは、型オブジェクトから値型への明示的な変換、またはインターフェイス型からインターフェイスを実装する値型への明示的な変換です。開箱操作は次のもので構成されます。

  • オブジェクトインスタンスをチェックして、指定された値タイプのボックス化された値であることを確認します。

  • インスタンスからvalue-type変数に値をコピーします。

ご覧のとおり、最初のステップは、オブジェクトインスタンスがターゲットタイプと一致することを確認することです。

また、ドキュメントから引用します。

実行時に値型のボックス化解除を成功させるには、ボックス化解除されるアイテムが、その値型のインスタンスをボックス化することによって以前に作成されたオブジェクトへの参照である必要があります。nullのボックスを解除しようとすると、NullReferenceExceptionが発生します。互換性のない値型への参照のボックスを解除しようとすると、InvalidCastExceptionが発生します。

したがって、このエラーを修正するには、開梱する前にタイプが一致することを確認してください。

object thirdTest = Convert.ToInt16(0);
short thirdtest2 = (short)thirdTest;  
于 2012-01-07T17:17:49.397 に答える
9

何が起こっているのかはまさにそれが言っていることです。

最初のケースでは、ボックス化されていない短いものがあり、intに明示的に型キャストしています。これは、コンパイラが実行方法を知っている有効な変換であるため、機能します。

2番目のケースでは、intに割り当てられている、ボックス化されたintがあります。これは整数の単純な開梱であり、これも有効なので、機能します。

3番目のケースでは、短いボックス化されたものがあります。これは、短いボックス化されていない変数にボックス化を解除しようとしています。これは有効な操作ではありません。これを1つのステップで実行することはできません。これも珍しい問題ではありません。たとえば、列SqlDataReaderを含むを使用している場合、次のSMALLINTことはできません。

    int x = (int)rdr["SmallIntColumn"];

次のいずれかが3番目の例で機能するはずです。

    object thirdTest = Convert.ToInt16(0);
    int thirdTest2 = Convert.ToInt32(thirdTest);
    int thirdTest3 = (int)(short)thirdTest;
于 2012-01-07T17:18:49.410 に答える
4

Int16書くための素晴らしい方法shortです; そこではボクシング/アンボクシングは行われず、16ビットと32ビットの整数間の単純なCLR変換だけが行われます。

2番目のケースは、同じ型にボックス化およびボックス化解除します。これは許可されています。値型intは、でラップされてから、ラップ解除されobjectます。

3番目のケースは、許可されていない別のタイプ(intではなく)にボックスを解除しようとしshortます。

于 2012-01-07T17:19:19.040 に答える