Matias Cicero
Matias Cicero

Reputation: 26281

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

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);

Upvotes: 27

Views: 11334

Answers (5)

jwdonahue
jwdonahue

Reputation: 6659

Type is a run-time reference to a TypeInfo object. It is not known until run-time where that TypeInfo object will reside.

Upvotes: 1

Christoph
Christoph

Reputation: 3642

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.

Upvotes: 11

D Stanley
D Stanley

Reputation: 152511

From MSDN:

Constants can be numbers, Boolean values, strings, or a null reference.

Constants are basically limited to primitive values that can be represented as a binary value at compile-type (since it is "injected" into the client code when it is compiled). Since Type is a class that has several properties, there's not a simple binary representation that can be "baked into" the client code.

Upvotes: 2

Kapol
Kapol

Reputation: 6463

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)

Upvotes: 13

Joshua Dannemann
Joshua Dannemann

Reputation: 2080

public const Type INT_TYPE = typeof(int);

The reason the above code will not compile is the exact reason stated by MSDN- the value of the constant cannot be determined at the time the application is compiled. Using typeof(int) requires determining the value for the constant at runtime. In theory, .NET could allow the statement above to compile, but then it would not be a constant in a strict sense of the word.

Upvotes: 0

Related Questions