查看以下LINQPad计划:
void Main() { }
[TestAttribute(Name)]
public class Test
{
public const string Name = "Test";
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
[Serializable]
public class TestAttribute : Attribute
{
public TestAttribute(string dummy)
{
}
}
这样编译没有任何障碍。为什么呢?
具体做法是:
[TestAttribute(Name)]
public class Test
{
public const string Name = "Test";
为什么我不写这个:
vvvvv
[TestAttribute(Test.Name)]
public class Test
{
public const string Name = "Test";
属性声明是否被认为是“内部”类型,因此在范围内?
答案 0 :(得分:2)
属性实例声明的范围确实是它所附加的类型的范围,或者(在方法,参数等的情况下)包含它所附加的元素的类型。
我找不到任何具体的内容,尽管标准确实说:
可以在全局范围(指定包含程序集的属性)和类型声明(第16.6节),类成员声明(第17.1.4节),结构成员声明(第18.2节)中指定属性,interface-member-declarations(第20.2节),enum-member-declarations(第21.1节),accessor-declarations(第17.6.2节),event-accessor-declarations(第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#更清晰
答案 1 :(得分:1)
当您将TestAttribute
放在类上时,它会将其与该类关联,因此Name
字段将在范围内。
您可以在此处阅读有关属性及其工作方式的所有内容:http://msdn.microsoft.com/en-us/library/aa664611(v=vs.71).aspx