Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't a Type be used as a constant value?

Tags:

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);
like image 901
Matias Cicero Avatar asked Aug 25 '15 19:08

Matias Cicero


People also ask

What is the difference between constants and data values?

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.

What is the difference between a named constant and a variable?

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.

How do you define constants in C?

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.

What is the difference between <var_name> and <value>?

<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.


2 Answers

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)
like image 159
Kapol Avatar answered Oct 11 '22 23:10

Kapol


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.

like image 36
Christoph Avatar answered Oct 11 '22 21:10

Christoph