简体   繁体   English

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

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

Quoting MSDN - const (C# reference) : 引用MSDN - const(C#引用)

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. 因此,引用类型常量的唯一可能值是stringnull引用。

According to: typeof(T) vs. Object.GetType() performance , typeof(T) is a compile time expression. 根据: typeof(T)与Object.GetType()性能typeof(T)是一个编译时表达式。

So why can't a Type be a constant value? 那么为什么Type不能成为常数值呢?

The following code will not compile: 以下代码将无法编译:

public const Type INT_TYPE = typeof(int);

Constants are substituted by the compiler with literal values in the resulting IL code. 编译器使用生成的IL代码中的文字值替换常量。 But typeof is a method call: 但是typeof是一个方法调用:

typeof(int);

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

From MSDN : 来自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. 由于Type是一个具有多个属性的 ,因此没有一个简单的二进制表示可以“烘焙”到客户端代码中。

The C# compiler and IL certainly support types as constant expressions, at least in certain situations. C#编译器和IL肯定支持类型作为常量表达式,至少在某些情况下。 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: 该类型在编译器生成的代码中嵌入为字符串,上面的行编译为以下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
)

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). 如果检查二进制数据,您会注意到这是没有任何程序集标识的完全限定类名(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. 回答你的问题:我没有看到任何技术上的原因,为什么这不应该是可能的,我也无法想象阻止它的兼容性因素,因为没有序列化的程序集引用,因此声明这种类型的DLL仍然可以更新而不影响以前的编译类型引用它。

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. 上述代码无法编译的原因是MSDN声明的确切原因 - 在编译应用程序时无法确定常量的值。 Using typeof(int) requires determining the value for the constant at runtime . 使用typeof(int)需要在运行时确定常量的值。 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. 从理论上讲,.NET 可以允许上面的语句进行编译,但是从严格意义上说它不会是常量。

Type is a run-time reference to a TypeInfo object. Type是对TypeInfo对象的运行时引用 It is not known until run-time where that TypeInfo object will reside. 直到该TypeInfo对象将驻留的运行时才知道它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM