16

我们有一个自定义属性

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

4

3 回答 3

8

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

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

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

于 2012-05-28T15:43:16.283 回答
2

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

于 2012-05-28T15:53:49.567 回答
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 还查找动态添加的属性(在运行时添加)

2. 使用移除属性

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

于 2017-08-25T08:57:57.113 回答