It's pretty easy to understand what happens when you look at the available LDC instructions . Note the limited range of operand types available, there is a no version that loads a constant of type short. Just int, long, float and double. These restrictions are visible elsewhere, for example, the Opcodes.Add command is also limited, adding variables of one of the smaller types is not supported.
The IL instruction set has been specifically designed in such a way that it reflects the capabilities of a simple 32-bit processor. The processor to think about is the RISC type, they had their own mowing in the nineties. There are many 32-bit processor registers that can only work with 32-bit integers and IEEE-754 floating-point types. The Intel x86 core is not a good example, although it is used very often, it is a CISC design that actually supports loading and performing arithmetic for 8-bit and 16-bit operands. But this is more of a historical accident, it facilitated the mechanical translation of programs that started on 8-bit 8080 and 16-bit 8086 processors. But this feature does not come for free, manipulating 16-bit values โโactually costs an additional processor cycle.
Making IL a good combination with the capabilities of a 32-bit processor clearly makes the job of a guy doing jitter much easier. Storage locations can still be smaller, but only loads, stores, and conversions need to be supported. And only when necessary, your variable "a" is a local variable, which in any case occupies 32 bits in the stack frame or in cpu. Only stores in memory should be truncated to the desired size.
There is no ambiguity in the code snippet. The value of the variable must be inserted into the box, because Marshal.SizeOf () takes an argument of an object of type. The boxed value defines the type of the value with a type descriptor; it points to System.Int16. Marshal.SizeOf () has built-in knowledge to know that it takes 2 bytes.
These restrictions reflect the C # language and cause inconsistency. This type of compilation error forever refutes and annoys C # programmers:
byte b1 = 127; b1 += 1;
As a result of IL constraints, there is no add statement that accepts byte operands. They must be converted to the next larger compatible type, int in this case. Thus, it runs on a 32-bit RISC processor. Now the problem is, the 32-bit int result should be hammered back into the variable, which can only store 8 bits. C # language applies what the hammer itself is for the first purpose, but illogically requires a hammer in the second purpose.