The common language infrastructure has many built-in value types with special encoding directly supported by the virtual execution system. Many are frequently used in common managed languages such as C#. The following chart will help you determine the size of each.
| Category | Bits | Type | Description |
| Integral | 8 | System.Boolean | True/False |
| Integral | 16 | System.Char | Unicode 16-bit character |
| Integral | 8 | System.SByte | Signed 8-bit integer |
| Integral | 16 | System.Int16 | Signed 16-bit integer |
| Integral | 32 | System.Int32 | Signed 32-bit integer |
| Integral | 64 | System.Int64 | Signed 32-bit integer |
| Integral | 32/64 | System.IntPtr | Signed native integer |
| Integral | 8 | System.Byte | Unsigned 8-bit integer |
| Integral | 16 | System.UInt16 | Unsigned 16-bit integer |
| Integral | 32 | System.UInt32 | Unsigned 32-bit integer |
| Integral | 64 | System.UInt64 | Unsigned 64-bit integer |
| Integral | 32/64 | System.UIntPtr | Unsigned native integer |
| Floating Point | 32 | System.Single | 32-bit float |
| Floating Point | 64 | System.Double | 64-bit float |
| Typed Reference | 64/128 | System.TypedReference | Pointer and exact type |
Although System.Boolean is an integral type at the CLI level, C# provides no conversion to and from int. C++ does provide this functionality: false is treated as 0 and true is treated as 1. System.Char is convertible to an integer in C#.
System.Boolean is 1 byte (8 bits) in managed code, but it will be converted to the native Windows BOOL format, 4 bytes large, when marshaled.
Assert.AreEqual(1, sizeof(Boolean));
Assert.AreEqual(4, Marshal.SizeOf(new Boolean()));
System.Char is 2 bytes but Marshal.SizeOf reports it as 1 byte. System.Char is Unicode whereas a Windows char is a standard ASCII character. This is important if you are supporting non-English characters.
Assert.AreEqual(2, sizeof(Char));
Assert.AreEqual(1, Marshal.SizeOf(new Char()));
An astute reader may have noticed two glaring omissions from types assumed to be supported by the CLR.
System.String is not a value type, so it is not included here.
System.Decimal is an extended-precision type included the Extended Numeric Library. It differs from floating point types in that it represents significant digits without rounding errors inherent in machine-based types. It is still a value type, but it may differ in .NET implementations and has no known special encoding. Aside from its size of 128-bits, this is another reason why decimal is notoriously slow compared to floats. However, when precision is necessary, it is the better choice. I did not include it since it lacked special encoding.
Types consist of value and reference types, but there is a hierarchy that describes the type is better detail. In the type table, I listed integral and floating point types,and placed a few types some may not consider integral in that section due to the manner in which the VES treats it. System.TypedReference doesn’t fit in with other types as it represents a combination of a type and a value. It is not CLS-Compliant and is typically used for interop scenarios.
I included a few keywords here you may not be familiar with. If you would like more information on the CLI, VES, or libraries and profiles, leave a comment.