为什么属性的属性必须是可读的?

Jul*_*ner 15 c# attributes compiler-errors properties

请考虑以下属性.

internal class NiceAttribute : Attribute
{
  private string _stuff;

  public string Stuff
  {
    set { _stuff = value; }
  }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用该属性时[Nice(Stuff = "test")],编译器会给出以下错误.

'Stuff'不是有效的命名属性参数.命名属性参数必须是非readonly,static或const的字段,或者 是公共而非静态的读写属性.

要求财产可读的理由是什么?


更新
我将尝试绘制我的用例,以便在属性上具有只写属性.

interface ISettingsBuilder
{
  Settings GetSettings();
}

class SettingsAttribute : Attribute, ISettingsBuilder
{
  private readonly IDictionary<string, object> _settings =
    new Dictionary<string, object>();

  public Settings GetSettings()
  {
    // Use _settings to create an immutable instance of Settings
  }

  public string Stuff
  {
    set { _settings["Stuff"] = value; }
  }

  // More properties ...
}
Run Code Online (Sandbox Code Playgroud)

可能还有其他实现ISettingsBuilder.例如,提供一个很好的API来通过代码构建设置.

我最终通过抛出一个来实现我的吸气剂NotImplementedException.

  public string Stuff
  {
    get { throw new NotImplementedException(); }
    set { _settings["Stuff"] = value; }
  }
Run Code Online (Sandbox Code Playgroud)

你能想出一个更好的方法来做这样的事吗?

seh*_*ehe 7

我怀疑编译器使用了一个稍微误导的检查,看看你是否在这里访问私人财产

编辑 "我们"现在已找到实际来源.出于提供信息的目的,这里有完整的细分,但请随时跳到底部.
(注意应该如何针对Mono编译器提交bug.我会认为这个问题已经过了一段时间)

编译器错误CS0617

'reference'不是有效的命名属性参数.命名属性参数必须是非readonly,static或const的字段,或非静态的读写属性.

尝试访问属性类的私有成员.

这可能似乎它正在使用某种形式的查找(类似于反射),以确保该吸气剂可访问的,如果不是的话,得出结论认为,它必须是私有的.

其中,当然,它不需要是:)

单声道兼容性:

为了好玩,请注意单声道编译器在接受此属性时没有任何问题:https://ideone.com/45fCX

因为反思:

当然,可能是编译器要求属性参数具有可反映的值.如果属性不是公开可读的,则只能使用反射来"观察"属性存在,而不是使用它初始化的参数.

我不确切地知道,为什么会有这样的设计选择,但如果考虑到反射的使用,它确实有意义.

更新 @Arun发布了确认此猜想的相关引用(谢谢!):

通过反射访问属性一旦属性与程序元素相关联,就可以使用反射来查询它们的存在和值.查询属性的主要反射方法包含在System.Reflection.MemberInfo类(GetCustomAttributes方法系列)中.

原因必须是:属性参数必须具有可反射的值

奖项问题:如何处理位置参数?如何反映这些?