在派生类上覆盖customattribute

时间:2012-05-28 15:31:50

标签: c# .net inheritance custom-attributes

我们有自定义属性

[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获取默认值的最佳模式是什么?

3 个答案:

答案 0 :(得分:7)

不,不可能覆盖现有属性。

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

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

答案 1 :(得分:1)

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

1。使用TypeDescriptor

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,您必须以两种方式遍历属性列表并过滤。你必须知道这些列表的顺序,如果大多数派生类型是第一个或反过来。

答案 2 :(得分:0)

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