【问题标题】:How to make a Attribute aware of the Name of the Proprty it is on?如何让属性知道它所在的属性的名称?
【发布时间】:2009-10-20 06:47:09
【问题描述】:

我想实现一个简单的属性,用于将数据库列映射到属性。

所以到目前为止我所拥有的东西是这样附加的:

    [DataField("ID")]
    public int ID { get; set; }

    [DataField("Name")]
    public String Name { get; set; }

    [DataField("BirD8")]
    public DateTime BirthDay { get; set; }

有没有一种方法可以让属性“感知”它所在的字段,以便对于名称与 ColumnName 相同的属性,我可以只应用不带名称参数的属性,或者我必须在反映属性的地方处理这个问题。我想最终做到这一点:

    [DataField]
    public int ID { get; set; }

    [DataField]
    public String Name { get; set; }

    [DataField("BirD8")]
    public DateTime BirthDay { get; set; }

【问题讨论】:

    标签: c# attributes custom-attributes


    【解决方案1】:

    属性本身不会知道它应用于什么,但代码处理属性可能会通过PropertyInfo 值等运行并找到与它们关联的属性。 代码然后可以适当地使用属性和属性。

    为了使事情更简单,您可能希望在属性上编写一个方法,以允许其将其信息与来自属性的信息合并,因此您可以调用:

    DataFieldAttribute dfa = propertyInfo.GetCustomAttributes(...); // As normal
    dfa = dfa.MergeWith(propertyInfo);
    

    请注意,为了保持理智,这应该创建一个新的属性实例,而不是更改现有的实例。或者,您可能想要一个完整的单独类来表示“有关数据字段的信息”:

    DataFieldAttribute dfa = propertyInfo.GetCustomAttributes(...); // As normal
    DataFieldInfo info = dfa.MergeWith(propertyInfo);
    

    这样你也可以构造DataFieldInfo对象而不引用任何属性,这可能是一个很好的概念分离 - 允许你轻松地从 XML 文件或类似文件加载配置,如果你想要。

    【讨论】:

    • 当您不拥有处理属性的代码时,就会出现问题。我们在本地化属性方面面临这个问题,它也可能是验证属性和其他方面的问题。我们有一些属性,我们需要将属性的名称和定义它的类的类型作为参数传递——这真的很糟糕。
    • 如果您不拥有处理属性的代码,那么大概它是在假设属性始终具有的限制的情况下设计的 - 即您无法访问目标。我同意这有点痛苦。
    • 谢谢。我设法在我反映属性的解决方案中进行了撬棍。
    【解决方案2】:

    如果您不介意使用 postsharp,您可以查看 Here,在我之前问过的问题中哪个很接近。尽管还有其他选项,例如 CompileTimeInitalize,但我最终还是使用了编译时验证来做我想做的事情。

    public override void CompileTimeInitialize(object element)
    {
        PropertyInfo info = element as PropertyInfo;
    
        //....
    }
    

    【讨论】:

    • 谢谢。我不能在这里使用这种方法,但我现在知道 postsharp 存在以及它可以做什么。非常感谢。
    猜你喜欢
    • 2016-04-18
    • 1970-01-01
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    • 2021-01-27
    相关资源
    最近更新 更多