我们有自定义属性
[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获取默认值的最佳模式是什么?
答案 0 :(得分:7)
不,不可能覆盖现有属性。
属性是附加到对象(程序集,类,方法,变量等)的元数据,因此它们始终保持此连接。
如果要在基类中提供默认的“行为”并在某些派生类中覆盖它,则必须检查GetCustomAttributes()
返回的所有属性,以便仅使用派生的最多(第一个)列表)。
答案 1 :(得分: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还会找到动态添加的属性(在运行时添加)
您可以向bool Remove { get; set; }
添加公开CustomDesignerAttribute
。您可以在派生类中将其设置为true
,同时将其他参数设置为与要删除的基类属性相同的参数。然后使用相同的键添加另一个属性,但将所需的值添加到派生类。获取属性时,您必须以智能方式评估Remove属性。使用类型1)中的TypeDescriptor和TypeId
,例如返回Key.HashCode() + Value.GetHashCode()
或使用GetType().GetCustomAttributes
,您必须以两种方式遍历属性列表并过滤。你必须知道这些列表的顺序,如果大多数派生类型是第一个或反过来。
答案 2 :(得分:0)
使用[AttributeUsage(Inherited=false)]
来防止派生类继承该属性。