我知道它们是编译时,因此它们不能是通用的,必须用常量值初始化.但是:
如果你反映出他们申请的内容,他们为什么不能获得你会得到的信息呢?
为什么他们不能接受lambda表达式,函数或委托?编译器的函数不是常量吗?
如果上面只有一个是真的,属性可能是一个非常强大的声明工具,相反,它们更像是可以通过反射阅读的注释.
这有点像咆哮,但我真的想知道为什么它们看起来像这样的半特征.
这就是我想要做的.它应该是一个API,用于将资源中的值通过给定属性的函数映射到属性应用的属性.请注意,如果Attributes可以知道它们反映的内容,则抽象类不必存在.我发布这个是因为有人想知道我为什么要为属性构造函数赋予函数,也许是因为我想要做的事情已经完成了.
public delegate void PropertyHandler(object parent, PropertyInfo property, object value);
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FromResourceAttribute : Attribute
{
private static readonly PropertyHandler m_defaultHandler = (parent, property, value) =>
{
property.SetValue(parent, value, null);
};
public PropertyHandler Handler { get; set; }
public FromResourceAttribute(PropertyHandler handler)
{
Handler = handler;
}
public FromResourceAttribute()
{
Handler = m_defaultHandler;
}
}
public abstract class ResourceDependent
{
public ResourceDependent(ResourceManager resources)
{
var resourceDependentProperties =
from property in GetType().GetProperties()
let fromResourceAttributes = property.GetCustomAttributes(typeof(FromResourceAttribute), true)
where fromResourceAttributes.Count() == 1
let propertyHandler = ((FromResourceAttribute)fromResourceAttributes.Single()).Handler
select new { Info = property, Handler = propertyHandler };
foreach(var property in resourceDependentProperties)
{
property.Handler(this, property.Info, resources.GetObject(property.Info.Name));
}
}
}
class ResourceDependentTest : ResourceDependent
{
[FromResource]
public string Data { get; set; }
[FromResource((parent, property, value) => property.SetValue(parent, ((string)value).Split('|'), null))]
public string[] Data2 { get; set; }
static PropertyHandler Data3Handler = (parent, property, value) =>
{
//Magic
};
[FromResource(Data3Handler)]
public int Data3 { get; set; }
public ResourceDependentTest() : base(Properties.Resources.ResourceManager)
{
}
}
Run Code Online (Sandbox Code Playgroud)
Jar*_*Par 11
部分原因是属性不必应用于任何事物.在命令式代码中新建一个属性是完全合法的,这个属性没有附加到任何东西上.
// Not attached
var attrib = new CLSCompliantAttribute(false);
Run Code Online (Sandbox Code Playgroud)
所有这些都解决了为什么委托不能成为属性的一部分的问题.核心代表由两部分组成:1)实例和2)指向方法的指针.#1非常杀死它,因为实例不是常量,不能是属性值的一部分.
委托中还存在其他几种情况,包括静态方法和表达式树的委托.虽然表达式的所有部分都不是常量,因此它们具有类似的问题,因此不能在属性值中编码.
事实上,关于他们为什么不能通用的问题之前已经得到了回答,并且根据Eric Lippert的说法,他们不受支持只是因为他们会增加语言的复杂性,而且到目前为止还没有被认为值得做.这肯定不是因为它是编译时间.在IL中,你显然可以创建通用属性.(参考.)
至于为什么他们不能采用lambda表达式等等,我想它也是同样的道理.自2006年以来,使用代理的请求一直是Microsoft Connect.如果您愿意,可以投票给它.