为什么可以使用C#中的反射读取常量上的属性?

为什么可以使用C#中的反射读取常量上的属性?,c#,reflection,constants,C#,Reflection,Constants,我在玩弄反射,无意中我意识到我可以在const类变量上放置一个自定义字段属性,然后(使用反射)读取类的字段,找到带有该属性的const并执行操作。这很好用 我很好奇为什么它工作得很好。除非我不理解常量是如何工作的,否则我认为常量是“编译出来的”,所有对该常量的引用在编译后都会变成常量的实际值。如果是这种情况,为什么反射仍然可以看到常量值?所有对常量的引用都被编译掉了,而不是常量声明本身。任何const声明都由编译器作为IL的一部分发出 下面是一个示例(请注意,IL保留了const字段) C#:

我在玩弄反射,无意中我意识到我可以在const类变量上放置一个自定义字段属性,然后(使用反射)读取类的字段,找到带有该属性的const并执行操作。这很好用

我很好奇为什么它工作得很好。除非我不理解常量是如何工作的,否则我认为常量是“编译出来的”,所有对该常量的引用在编译后都会变成常量的实际值。如果是这种情况,为什么反射仍然可以看到常量值?

所有对
常量的引用都被编译掉了,而不是
常量
声明本身。任何
const
声明都由编译器作为IL的一部分发出

下面是一个示例(请注意,IL保留了
const
字段)

C#:

class Foo
{
    const int i = 0;
}
.class private auto ansi beforefieldinit Foo
    extends [mscorlib]System.Object
{
    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
    }


    .field private static literal int32 i = int32(0)    
}
IL:

class Foo
{
    const int i = 0;
}
.class private auto ansi beforefieldinit Foo
    extends [mscorlib]System.Object
{
    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
    }


    .field private static literal int32 i = int32(0)    
}
我认为常量是“编译出来的”,所有对该常量的引用在编译后都成为常量的实际值。如果是这样的话


我认为情况并非如此。
const
仍然是其类中成熟的成员。考虑一个公开<<代码>公共const 的库。甚至可能没有任何要“编译”的引用(在库本身中)。

好吧,假设世界按照您想象的方式运行。如果程序集中没有嵌入常量的元数据,那么如何使用程序集中定义的常量值?这不是一个反问句;我真正感兴趣的是,为什么人们相信编程语言的奇怪之处,以便我们将来能够制作更好的语言和文档。@Eric Lippert:我想这是因为其他编程语言都是这样工作的,尤其是人们以前遇到的编程语言。我从未假设在.NET中编译出常量,但如果有人提到它们,我并不感到惊讶,因为这与我对Delphi或C的了解是一致的。此外,正如人们所说,关于常量的一些内容被编译掉了,这需要进一步认识到,在变得清楚常数本身并没有从集合中移除之前。