为什么C#属性如此有限?

cor*_*ory 7 c# attributes

我知道它们是编译时,因此它们不能是通用的,必须用常量值初始化.但是:
如果你反映出他们申请的内容,他们为什么不能获得你会得到的信息呢?
为什么他们不能接受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)

为什么他们不能接受lambda表达式,函数或委托?编译器的函数不是常量吗?

所有这些都解决了为什么委托不能成为属性的一部分的问题.核心代表由两部分组成:1)实例和2)指向方法的指针.#1非常杀死它,因为实例不是常量,不能是属性值的一部分.

委托中还存在其他几种情况,包括静态方法和表达式树的委托.虽然表达式的所有部分都不是常量,因此它们具有类似的问题,因此不能在属性值中编码.


Ric*_*ein 5

事实上,关于他们为什么不能通用的问题之前已经得到了回答,并且根据Eric Lippert的说法,他们不受支持只是因为他们会增加语言的复杂性,而且到目前为止还没有被认为值得做.这肯定不是因为它是编译时间.在IL中,你显然可以创建通用属性.(参考.)

至于为什么他们不能采用lambda表达式等等,我想它也是同样的道理.自2006年以来,使用代理的请求一直是Microsoft Connect.如果您愿意,可以投票给它.