【问题标题】:Overwrite customattribute on derived class覆盖派生类中的自定义属性
【发布时间】:2012-06-02 23:08:46
【问题描述】:

我们有一个自定义属性

[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class CustomDesignerAttribute: Attribute

那么我们就有了一个用这个属性装饰的基类

[CustomDesigner(someKey, someValue)]
public class BaseClass

然后我们有一个从这个派生的类,用相同的属性装饰(具有相同的键,不同的值)

[CustomDesigner(someKey, someOtherValue)]
public class ChildClass : BaseClass

是否有可能 ChildClass 不创建属性的副本,而是覆盖现有键的值(覆盖整个父属性)? 如果没有,如果 ChildClass 没有定义自己的,从 BaseClass 获取默认值的最佳模式是什么?

【问题讨论】:

  • 我不确定,所以我会留下这个作为评论:也许禁用属性继承是一个解决方案。

标签: c# .net inheritance custom-attributes


【解决方案1】:

不,无法覆盖现有属性。

属性是附加到对象(程序集、类、方法、变量等)的元数据,因此它们始终保持这种连接

如果您想在基类中提供默认的“行为”并在某些派生类中覆盖它,您必须检查GetCustomAttributes() 返回的所有属性以仅使用最派生的属性(列表中的第一个) .

【讨论】:

    【解决方案2】:

    使用[AttributeUsage(Inherited=false)] 防止属性被派生类继承。

    【讨论】:

    • 但是如果 BaseClass 被许多派生类共享,那么他将没有“默认”并且他必须为每个派生类重复属性(此外,如果基类是抽象的,那么属性本身将无用)
    • 不走运,如果 BaseClass 是抽象的,则没有变化
    【解决方案3】:

    我认为可以通过以下方式:

    1。使用类型描述符

    在您的CustomDesignerAttribute 中覆盖TypeId

    public override object TypeId
    {
         get
         {
             return Key.GetHashCode();
          }
     }
    

    TypeId 的基本实现只使用了属性类型,因此不会涉及任何参数。

    然后你可以使用 TypeDescriptor.GetAttributes(typeof(ChildClass)).OfType<CustomDesignerAttribute>()

    TypeDescriptor(与GetType().GetCustomAttributes 不同)仅返回一个基于相同TypeId 的属性。我对其进行了测试,它是与返回的TypeId 匹配的最派生属性。

    因此,如果您的 TypeId 代表属性的键,那么您可以在派生类上覆盖它 - 当使用 TypeDescriptor 获取属性时!请注意,仍然可以使用多个属性,只要它们的键不同。

    注意:TypeDescriptor 还查找动态添加的属性(在运行时添加)

    2。使用删除属性

    您可以将公共bool Remove { get; set; } 添加到您的CustomDesignerAttribute。您可以在派生类中将其设置为true,同时将其他参数设置为与要删除的基类属性相同。然后将另一个具有相同键但您想要的值的属性添加到派生类。获取属性时,您必须以智能的方式评估 Remove 属性。使用 1) 中的 TypeDescriptor 和 TypeId 例如返回Key.HashCode() + Value.GetHashCode() 或使用GetType().GetCustomAttributes,在这两种方式中,您都必须遍历属性列表和过滤器。您必须知道这些列表的顺序是最先派生的类型还是相反。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 2013-05-01
      相关资源
      最近更新 更多