引用MSDN - const (C# reference):
常量表达式是一个可以在编译时完全计算的表达式。因此,引用类型常量的唯一可能值是 string 和 null 引用。
根据:typeof(T) vs. Object.GetType() performance,typeof(T)
是编译时表达式。
那么为什么Type
不能成为常数值?
以下代码不会编译:
public const Type INT_TYPE = typeof(int);
答案 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)