为什么可以从属性访问私有 const 字段?
Why it is possible to access private const field from attribute?
怎么可能?
namespace test
{
class Attr:Attribute
{
public Attr(int e)
{
}
}
[Attr(E)]
class Test
{
private const int E = 0;
}
}
这不违反封装原则吗?
不,这不违反封装。属性声明在逻辑上是 class 的一部分。 Attr
没有访问 Test.E
(它不能),您正在从 Test
中用 E
调用 Attr
的构造函数。这与初始化成员一样好。
C# 语法可能使属性看起来像是 "outside" 或 class,但事实并非如此。为此 class 生成的 IL 是这样的:
.class private auto ansi beforefieldinit test.Test
extends [mscorlib]System.Object
{
.custom instance void test.Attr::.ctor(int32) = (
01 00 00 00 00 00 00 00
)
// Fields
.field private static literal int32 E = int32(0)
...
} // end of class test.Test
如果 C# 采用类似的语法,它可能看起来像这样:
class Test
{
attribute Attr(E);
private const int E = 0;
}
这会强调声明的范围,但可以说它不会那么清楚。当属性应用于成员(在 IL 中,这些直接跟在声明之后)时,它变得更加不清楚。
怎么可能?
namespace test
{
class Attr:Attribute
{
public Attr(int e)
{
}
}
[Attr(E)]
class Test
{
private const int E = 0;
}
}
这不违反封装原则吗?
不,这不违反封装。属性声明在逻辑上是 class 的一部分。 Attr
没有访问 Test.E
(它不能),您正在从 Test
中用 E
调用 Attr
的构造函数。这与初始化成员一样好。
C# 语法可能使属性看起来像是 "outside" 或 class,但事实并非如此。为此 class 生成的 IL 是这样的:
.class private auto ansi beforefieldinit test.Test
extends [mscorlib]System.Object
{
.custom instance void test.Attr::.ctor(int32) = (
01 00 00 00 00 00 00 00
)
// Fields
.field private static literal int32 E = int32(0)
...
} // end of class test.Test
如果 C# 采用类似的语法,它可能看起来像这样:
class Test
{
attribute Attr(E);
private const int E = 0;
}
这会强调声明的范围,但可以说它不会那么清楚。当属性应用于成员(在 IL 中,这些直接跟在声明之后)时,它变得更加不清楚。