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)
你能想出一个更好的方法来做这样的事吗?
我怀疑编译器使用了一个稍微误导的检查,看看你是否在这里访问私人财产
编辑 "我们"现在已找到实际来源.出于提供信息的目的,这里有完整的细分,但请随时跳到底部.
(注意应该如何针对Mono编译器提交bug.我会认为这个问题已经过了一段时间)
'reference'不是有效的命名属性参数.命名属性参数必须是非readonly,static或const的字段,或非静态的读写属性.
尝试访问属性类的私有成员.
这可能似乎它正在使用某种形式的查找(类似于反射),以确保该吸气剂是可访问的,如果不是的话,得出结论认为,它必须是私有的.
其中,当然,它不需要是:)
为了好玩,请注意单声道编译器在接受此属性时没有任何问题:https://ideone.com/45fCX
当然,可能是编译器要求属性参数具有可反映的值.如果属性不是公开可读的,则只能使用反射来"观察"属性存在,而不是使用它初始化的参数.
我不确切地知道,为什么会有这样的设计选择,但如果考虑到反射的使用,它确实有意义.
更新 @Arun发布了确认此猜想的相关引用(谢谢!):
通过反射访问属性一旦属性与程序元素相关联,就可以使用反射来查询它们的存在和值.查询属性的主要反射方法包含在System.Reflection.MemberInfo类(GetCustomAttributes方法系列)中.
原因必须是:属性参数必须具有可反射的值
奖项问题:如何处理位置参数?如何反映这些?
| 归档时间: |
|
| 查看次数: |
539 次 |
| 最近记录: |