C# 为什么这是合法的?从类型上的属性*引用类型中的常量,而不使用类型名称作为前缀?

C# 为什么这是合法的?从类型上的属性*引用类型中的常量,而不使用类型名称作为前缀?,c#,attributes,constants,C#,Attributes,Constants,请看以下程序: 这样编译起来很顺利。为什么? 具体而言: [TestAttribute(Name)] public class Test { public const string Name = "Test"; 为什么我不写这个: vvvvv [TestAttribute(Test.Name)] public class Test { public const string Name = "Test"; 属性声明是否被视为“在”类型内,因此在范围

请看以下程序:

这样编译起来很顺利。为什么?

具体而言:

[TestAttribute(Name)]
public class Test
{
    public const string Name = "Test";
为什么我不写这个:

               vvvvv
[TestAttribute(Test.Name)]
public class Test
{
    public const string Name = "Test";

属性声明是否被视为“在”类型内,因此在范围内?

当您将
TestAttribute
放在类上时,它会将其与该类关联,因此
Name
字段将在范围内


您可以在此处阅读有关属性及其工作方式的所有信息:

属性实例声明的范围实际上是它所附加的类型的范围,或者(对于方法、参数等)包含它所附加的元素的类型

我找不到关于这方面的任何具体内容,尽管标准确实规定:

可以在全局范围(指定包含程序集上的属性)和类型声明(§16.6)、类成员声明(§17.1.4)、结构成员声明(§18.2)、接口成员声明(§20.2)、枚举成员声明(§21.1)、访问器声明(§17.6.2)、事件访问器声明中指定属性(§17.7)、正式参数列表的元素(§17.5.1)和类型参数列表的元素(§25.1.1)

虽然它没有明确说明类范围,但它确实将其与“全局范围”中更广泛的全局属性范围区分开来

我注意到你们班的CIL是:

class public auto ansi beforefieldinit SomeNamespace.Test extends [mscorlib]System.Object
{
  .custom instance void SomeNamespace.TestAttribute::.ctor(string) = (
    01 00 04 54 65 73 74 00 00
  )
  .field public static literal string Name = "Test"
  .method public hidebysig specialname rtspecialname instance void .ctor () cil managed
  {
    .maxstack 8
    ldarg.0
    call instance void [mscorlib]System.Object::.ctor()
    ret
  }
}

CIL中的作用域比C#

中的作用域清楚得多,其中特别指出属性在类的作用域中?您正在向类添加属性,因此您的作用域不是基于属性,而是基于您将其添加到的类(在本例中为
Test
)文档对此不是很具体,但通过测试可以发现是这样的。
class public auto ansi beforefieldinit SomeNamespace.Test extends [mscorlib]System.Object
{
  .custom instance void SomeNamespace.TestAttribute::.ctor(string) = (
    01 00 04 54 65 73 74 00 00
  )
  .field public static literal string Name = "Test"
  .method public hidebysig specialname rtspecialname instance void .ctor () cil managed
  {
    .maxstack 8
    ldarg.0
    call instance void [mscorlib]System.Object::.ctor()
    ret
  }
}