C#中的常量


9

为何编译器将常量值存储在程序集元数据中?它们是否直接从程序集元数据嵌入到中间语言代码中?


1
这并没有真正解决“为什么”的问题,但是仍然很有趣:stackoverflow.com/a/2128633/128384
stijn 2013年

我对这个问题感到困惑。如果不在元数据中,它们还会存储在哪里?你能澄清这个问题吗?
Eric Lippert 2013年

Answers:


4

我发现最好的思考方式是:在编译时,将const转换为使用它的文字。

它进入定义清单的清单中的唯一原因是使它对消费者可用。它是给定类型的一部分,该类型的元数据存储在它的程序集中,而不是使用它的程序集中。

因此,它是消耗量的嵌入式文字,是元数据中可消耗的类型封装的属性或字段。


2

我研究了很长时间,从一本书中发现这可能就是原因。

由于常量值永远不变,因此常量被视为定义类型的一部分。因此,定义常量将创建元数据。


1

我认为您混合了两个程序集。

该常数仅存储在定义该常数的程序集中的元数据中。元数据包含有关程序集中所有类型和成员的信息,常量是成员。

在使用常量的程序集中没有存储有关常量的信息。常量值直接在IL中使用,就像您直接在源代码中写入常量数字或字符串一样。

一个例子:我的一个应用程序使用很多常量来标识数据库表和字段。我有一个只包含所有常量的程序集。

构建应用程序时,我在Visual Studio中添加了对“常量”程序集的引用。由于程序集仅包含常量,因此在我的应用程序中没有对其的引用,并且在运行时不需要“常量”程序集。


2
但是,这并不能真正解释为什么常量存储在元数据中。它围绕着为什么而跳舞,但我认为OP根本不会混淆两个程序集。您将其视为两个程序集的问题,因为您使用了两个程序集,但是我认为这种做法并不常见。常量通常在使用它们的同一程序集中定义。
罗伯特·哈维

@RobertHarvey您对典型案例的推定高估了我们许多企业级C#同事的技能,我不得不多次解释对同事来说const是什么,以及为什么您不跨程序集调用它们。
Jimmy Hoffa 2013年

1

常量在编译时是已知的,然后将它们存储在程序集的元数据中。这意味着您只能为基本类型定义常量。

是的,它们是直接从元数据加载的。运行时将没有内存分配。


1
十进制不是原始类型,但是您可以使十进制常量。只要常量为空,就可以制作任何引用类型的常量。
Eric Lippert 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.