Why does the Type class have a method called IsPrimitive() if the C# spec refers to them as simple types?

127 views Asked by At

Looking at the C# 6.0 Draft specification I saw nothing about primitive types; I only saw data about Simple types. That said, the Type class has an IsPrimitive method.

Should IsPrimitve really be IsSimple?

1

There are 1 answers

0
Jeroen Mostert On BEST ANSWER

The C# "simple types" are (alphabetically) bool, byte, char, decimal, double, float, int, long, sbyte, short, uint, ulong andushort . These are a set of struct types that C# has chosen to give special status, with special provisions other types don't get (as detailed in the standard), such as the ability to use them as constants.

Type.IsPrimitive is a different beast; it returns true for a limited set of value types (which C# formally calls "struct types", but very commonly called "value types" by C# developers anyway) that the runtime considers special in some way. These types are Boolean, Byte, Char, Double, Int16, Int32, Int64, IntPtr, SByte, Single, UInt16, UInt32, UInt64 and UIntPtr (all living in System). These types all have in common that they are directly supported by the runtime as built-in types, so they have operations that are directly implemented by the JIT compiler rather than as compiled IL. (There is one more value type that meets these criteria which is not on this list of types, for some reason: TypedReference. This is rarely used in managed languages and detailing its purpose and use is something for another answer.)

The most striking difference between these lists is that C#'s simple type decimal is not a primitive type. This has some consequences: C# allows decimal constants, but the runtime does not -- they are really compiled as static readonly fields with some attribute magic, as detailed by Jon Skeet here. The designers of C# considered decimal important enough to label it a simple type, but it's not a built-in type, so the compiler has to make up for the difference.

The other important difference is that IntPtr and UIntPtr are built-in types, but C# does not consider them "simple", presumably since you're not really supposed to make much use of them in managed code outside interop scenarios, and also because they have restrictions that would not be shared by other simple types (you cannot declare IntPtr constants, not even on the IL level, because the actual size differs by platform).

So the short answer is: no, Type.IsPrimitive should not be named Type.IsSimple, although "primitive type" does not really have a single definition that I can see, beyond the raw listing of the types. "Built-in value type" does have a definition, which is almost but not entirely the same as what Type.IsPrimitive calls "primitive".