Quoting MSDN - const (C# reference):
A constant expression is an expression that can be fully evaluated at compile time. Therefore, the only possible values for constants of reference types are string and a null reference.
According to: typeof(T) vs. Object.GetType() performance, typeof(T)
is a compile time expression.
So why can't a Type
be a constant value?
The following code will not compile:
public const Type INT_TYPE = typeof(int);
Data values that stay the same every time a program is executed are known as constants. Constants are not expected to change. Literal constants are actual values fixed into the source code. An example of this might be the character string "hello world". The data value "hello world" has been fixed into the code.
Named constants are values where a name is defined to be used instead of a literal constant. An example of this might be stating that the 'starting level' of a game is always referred to as 1. Variables are data values that can change when the user is asked a question, for example, their age. Variables may change during program execution.
When you're programming, there are times when you'll want the values of certain variables to remain unchanged. In the C language, you'll likely define them as constants. You can define constants in C in a few different ways. In this tutorial, you'll learn how to use #define and the const qualifier to define them. Let's get started.
<VAR_NAME> is a placeholder for the name of the constant. It's recommended that you name constants in the uppercase, as it helps differentiate them from other variables defined in the program. <VALUE> is a placeholder for the value that <VAR_NAME> takes.
Constants are substituted by the compiler with literal values in the resulting IL code. But typeof
is a method call:
typeof(int);
// Becomes:
L_0000: ldtoken int32
L_0005: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
The C# compiler and IL certainly support types as constant expressions, at least in certain situations. Look at attributes, they use this a lot:
[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
The type is embedded as a string in the compiler generated code, above line compiles to the following IL code:
.custom instance void System.Diagnostics.DebuggerTypeProxyAttribute::.ctor(class System.Type) = (
01 00 39 53 79 73 74 65 6d 2e 43 6f 6c 6c 65 63
74 69 6f 6e 73 2e 47 65 6e 65 72 69 63 2e 4d 73
63 6f 72 6c 69 62 5f 43 6f 6c 6c 65 63 74 69 6f
6e 44 65 62 75 67 56 69 65 77 60 31 00 00
)
If you inspect the binary data, you will notice this is the fully qualified class name without any assembly identification (System.Collections.Generic.Mscorlib_CollectionDebugView`1).
To answer your question: I do not see any technical reason why this should not be possible, nor can I imagine compatibility considerations that prevent it as there is no assembly reference serialized and therefore the DLL declaring this type still can be updated without affecting the previously compiled type referencing it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With