利用可能な LDC 命令を見れば、何が起こっているかを簡単に知ることができます。使用できるオペランドの型は限られていることに注意してください。short 型の定数をロードするバージョンはありません。int、long、float、double だけです。これらの制限は他の場所でも見られます。たとえば、Opcodes.Add 命令は同様に制限されており、小さい型の変数の追加はサポートされていません。
IL 命令セットは、意図的にこのように設計されており、単純な 32 ビット プロセッサの機能を反映しています。考えるべきプロセッサの種類は RISC の種類で、19 年代に干し草の日がありました。32 ビット整数と IEEE-754 浮動小数点型のみを操作できる 32 ビット CPU レジスタが多数あります。Intel x86 コアは良い例ではありませんが、非常に一般的に使用されていますが、8 ビットおよび 16 ビット オペランドのロードと演算を実際にサポートする CISC 設計です。しかし、それはむしろ歴史的な偶然であり、8 ビット 8080 および 16 ビット 8086 プロセッサで開始されたプログラムの機械的な変換が容易になりました。しかし、そのような機能は無料では提供されません。16 ビット値を操作するには、実際には追加の CPU サイクルが必要です。
IL を 32 ビット プロセッサの機能とうまく調和させることで、ジッターを実装する担当者の仕事が大幅に簡素化されます。ストレージの場所はさらに小さいサイズにすることができますが、ロード、ストア、および変換のみをサポートする必要があります。必要な場合にのみ、「a」変数はローカル変数であり、とにかくスタック フレームまたは cpu レジスタで 32 ビットを占有します。適切なサイズに切り詰める必要があるのは、メモリへのストアのみです。
それ以外の場合、コード スニペットにあいまいさはありません。Marshal.SizeOf() はobject型の引数を取るため、変数値をボックス化する必要があります。ボックス化された値は、型ハンドルによって値の型を識別し、System.Int16 を指します。Marshal.SizeOf() には、2 バイトかかることを知る組み込みの知識があります。
これらの制限は C# 言語に反映され、矛盾を引き起こします。この種のコンパイル エラーは、C# プログラマーを永遠に困惑させ、困惑させます。
byte b1 = 127;
b1 += 1; // no error
b1 = b1 + 1; // error CS0266
これは IL の制限の結果であり、バイト オペランドを取る加算演算子はありません。これらは、互換性のある次に大きな型 (この場合はint )に変換する必要があります。したがって、32 ビット RISC プロセッサで動作します。ここで問題があります。32 ビットのintの結果を、8 ビットしか格納できない変数に戻す必要があります。C# 言語は、1 番目の割り当てでハンマー自体を適用しますが、2 番目の割り当てでは非論理的にキャスト ハンマーを必要とします。