为什么不能将Type用作常量值?

时间:2015-08-25 19:49:44

标签: c# .net types reference const

引用MSDN - const (C# reference)

  

常量表达式是一个可以在编译时完全计算的表达式。因此,引用类型常量的唯一可能值是 string null 引用。

根据:typeof(T) vs. Object.GetType() performancetypeof(T)是编译时表达式。

那么为什么Type不能成为常数值?

以下代码不会编译:

public const Type INT_TYPE = typeof(int);

5 个答案:

答案 0 :(得分:5)

编译器使用生成的IL代码中的文字值替换常量。但typeof是方法调用:

typeof(int);

// Becomes:
L_0000: ldtoken int32
L_0005: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)

答案 1 :(得分:2)

来自MSDN

  

常量可以是数字,布尔值,字符串或空引用。

常量基本上限于原始值,可以在编译类型中表示为二进制值(因为它在编译时被“注入”客户端代码中)。由于Type是一个具有多个属性的,因此没有一个简单的二进制表示可以“融入”客户端代码。

答案 2 :(得分:2)

C#编译器和IL肯定支持类型作为常量表达式,至少在某些情况下如此。看看属性,他们经常使用它:

[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]

该类型作为字符串嵌入编译器生成的代码中,上面的行编译为以下IL代码:

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

如果检查二进制数据,您会注意到这是完全限定的类名而没有任何程序集标识(System.Collections.Generic.Mscorlib_CollectionDebugView`1)。

回答你的问题:我没有看到任何技术上的原因,为什么这不应该是可能的,我也无法想象阻止它的兼容性因素,因为没有序列化的程序集参考,因此声明这种类型的DLL仍然可以更新影响引用它的先前编译类型。

答案 3 :(得分:0)

                     datetime   latitude  longitude  weekday
1     2015-08-25 17:10:53.920  52.232342   0.134956        1

上述代码无法编译的原因是MSDN声明的确切原因 - 在编译应用程序时无法确定常量的值。使用typeof(int)需要在运行时确定常量的值。从理论上讲,.NET 可以允许上面的语句进行编译,但从严格意义上说它不会是常量。

答案 4 :(得分:0)

Type是对TypeInfo对象的运行时 引用 。直到运行时为止,该TypeInfo对象将驻留在哪里。