为什么属性成员需要public?
Why do Attribute members need to be public?
问题
正在尝试使用属性
internal class FooAttribute : Attribute
{
internal string Bar { get; set; }
}
像这样
[Foo(Bar = "hello world")]
public class MyOtherClass { }
(在同一个程序集中)产生
error CS0617: 'Bar' is not a valid named attribute argument. Named attribute arguments must be fields which are not readonly, static, or const, or read-write properties which are public and not static.
但是,我可以完美地从 "in code" 访问 Bar
,例如
FooAttribute attribute = new FooAttribute { Bar = "hello world" };
解决方案
但是,如果我将属性更改为
internal class FooAttribute : Attribute
{
public string Bar { get; set; }
^^^^^^
}
我可以按预期使用它。
请注意,我只需要标记 属性 public
- 而不是属性本身。尽管 有效地 没有改变 Bar
.
的可见性,但这“解决了”问题
为什么在这种情况下属性是“特殊的”——为什么编译器要求它们的字段是 public?
documentation on the error也没有提到为什么他们也需要public。
Why are attributes "special" in this case
您将错误的部分识别为特殊的。属性的特殊之处在于,对于与字段、classes、方法等关联的对象,public 属性有一种构造和设置组合的语法
换句话说,属性的特殊之处在于它们是属性!
事实上,它甚至不是特殊的属性;正如您自己所说,您可以使用与任何其他初始化程序相同的初始化程序创建相同 class 的实例。这是特殊的属性语法。
它必须允许调用 public 构造函数(否则永远不可能构造)并且它必须允许设置 public 属性(否则永远不会设置属性) .还值得注意的是,这早于将初始化语法引入 C# 之前,因此曾几何时,在属性的情况下,只能将 public 属性的构造和立即设置组合在一个语法单元中。
如此考虑,与初始化器的工作方式相比毫无意义,因为在做出相关设计决策时它们并不存在。
所以,让我们单独考虑 [Foo(Bar = "hello world")]
,并考虑什么时候可以这样设置 Bar
。
当 Bar
为 public 时允许它的原因应该很明显。
当 Bar
是私有的时不允许它的原因也应该很明显。
当其内部有两个合理的选择时;当属性存在于给定程序集中时不允许或允许。
所以问题是拥有一个 public 的属性有多大用处(如果它本身是内部的,我们可以用所有 -public 属性实现同样的事情)因此可以在其他程序集中使用,但具有只能在同一程序集中使用的属性中设置的内部属性。如果这是超级有用的,那么允许它的额外工作和复杂性将是值得的。如果它不是超级有用,那么理论(规范)和实践(编译器)都最好不要允许它。
它似乎没有被认为是超级有用的。
问题
正在尝试使用属性
internal class FooAttribute : Attribute
{
internal string Bar { get; set; }
}
像这样
[Foo(Bar = "hello world")]
public class MyOtherClass { }
(在同一个程序集中)产生
error CS0617: 'Bar' is not a valid named attribute argument. Named attribute arguments must be fields which are not readonly, static, or const, or read-write properties which are public and not static.
但是,我可以完美地从 "in code" 访问 Bar
,例如
FooAttribute attribute = new FooAttribute { Bar = "hello world" };
解决方案
但是,如果我将属性更改为
internal class FooAttribute : Attribute
{
public string Bar { get; set; }
^^^^^^
}
我可以按预期使用它。
请注意,我只需要标记 属性 public
- 而不是属性本身。尽管 有效地 没有改变 Bar
.
为什么在这种情况下属性是“特殊的”——为什么编译器要求它们的字段是 public?
documentation on the error也没有提到为什么他们也需要public。
Why are attributes "special" in this case
您将错误的部分识别为特殊的。属性的特殊之处在于,对于与字段、classes、方法等关联的对象,public 属性有一种构造和设置组合的语法
换句话说,属性的特殊之处在于它们是属性!
事实上,它甚至不是特殊的属性;正如您自己所说,您可以使用与任何其他初始化程序相同的初始化程序创建相同 class 的实例。这是特殊的属性语法。
它必须允许调用 public 构造函数(否则永远不可能构造)并且它必须允许设置 public 属性(否则永远不会设置属性) .还值得注意的是,这早于将初始化语法引入 C# 之前,因此曾几何时,在属性的情况下,只能将 public 属性的构造和立即设置组合在一个语法单元中。
如此考虑,与初始化器的工作方式相比毫无意义,因为在做出相关设计决策时它们并不存在。
所以,让我们单独考虑 [Foo(Bar = "hello world")]
,并考虑什么时候可以这样设置 Bar
。
当 Bar
为 public 时允许它的原因应该很明显。
当 Bar
是私有的时不允许它的原因也应该很明显。
当其内部有两个合理的选择时;当属性存在于给定程序集中时不允许或允许。
所以问题是拥有一个 public 的属性有多大用处(如果它本身是内部的,我们可以用所有 -public 属性实现同样的事情)因此可以在其他程序集中使用,但具有只能在同一程序集中使用的属性中设置的内部属性。如果这是超级有用的,那么允许它的额外工作和复杂性将是值得的。如果它不是超级有用,那么理论(规范)和实践(编译器)都最好不要允许它。
它似乎没有被认为是超级有用的。