自定义属性在抽象属性上的继承

时间:2010-03-25 23:00:05

标签: c# reflection attributes abstract-class

我有一个自定义属性,我想应用于我的基本抽象类,以便我可以跳过在HTML中显示项目时用户不需要查看的元素。似乎覆盖基类的属性不继承属性。

重写基本属性(抽象或虚拟)是否会破坏原始属性上的属性?

来自属性类定义

[AttributeUsage(AttributeTargets.Property,
                Inherited = true,
                AllowMultiple = false)]
public class NoHtmlOutput : Attribute
{
}

来自抽象类定义

[NoHtmlOutput]
public abstract Guid UniqueID { get; set; }

来自具体类定义

public override Guid UniqueID{ get{ return MasterId;} set{MasterId = value;}}

从类检查属性

        Type t = o.GetType();
        foreach (PropertyInfo pi in t.GetProperties())
        {
            if (pi.GetCustomAttributes(typeof(NoHtmlOutput), true).Length == 1)
                continue;
            // processing logic goes here
        }

5 个答案:

答案 0 :(得分:60)

您必须调用静态方法System.Attribute.GetCustomAttributes(pi,...),而不是调用PropertyInfo.GetCustomAttributes(...),如下所示:

PropertyInfo info = GetType().GetProperties();

// this gets only the attributes in the derived class and ignores the 'true' parameter
object[] DerivedAttributes = info.GetCustomAttributes(typeof(MyAttribute),true);

// this gets all of the attributes up the heirarchy
object[] InheritedAttributes = System.Attribute.GetCustomAttributes(info,typeof(MyAttribute),true);

答案 1 :(得分:30)

不,属性是继承的。

GetCustomAttributes()方法不查看父声明。它仅查看应用于指定成员的属性。 From the docs

  

说明

     

此方法忽略继承   属性和事件的参数。   搜索继承链   属性和事件的属性,   使用适当的重载   属性.. ::。GetCustomAttributes   方法

答案 2 :(得分:0)

看起来只有当覆盖方法也具有属性时才会发生。

http://msdn.microsoft.com/en-us/library/a19191fh.aspx

但是,您可以覆盖相同类型的属性或将其他属性应用于派生组件。以下代码片段显示了一个自定义控件,它通过覆盖基类中应用的BrowsableAttribute属性来覆盖从Control继承的Text属性。 Visual Basic

Public Class MyControl
   Inherits Control
   ' The base class has [Browsable(true)] applied to the Text property.
   <Browsable(False)>  _
   Public Overrides Property [Text]() As String
      ...
   End Property 
   ...
End Class

答案 3 :(得分:0)

这是我的尝试。这是MemberInfo上的一种扩展方法,它手动遍历继承层次结构。这似乎与动态代理兼容...至少由Castle创建的软管,所以我假设它将与任何代理库兼容。

public static IEnumerable<T> GetCustomAttributes<T>(this MemberInfo instance)
{
    while (instance != null)
    {
        object[] attributes = instance.GetCustomAttributes(typeof(T), false);
        if (attributes.Length > 0)
        {
            return attributes.Cast<T>();
        }
        Type ancestor = instance.DeclaringType.BaseType;
        if (ancestor != null)
        {
            IEnumerable<MemberInfo> ancestormatches = ancestor.FindMembers(instance.MemberType, BindingFlags.Instance | BindingFlags.Public, 
                (m, s) =>
                {
                    return m.Name == (string)s;
                }, instance.Name);
            instance = ancestormatches.FirstOrDefault();
        }
        else
        {
            instance = null;
        }
    }
    return new T[] { };
}

你会像这样使用它。

Type t = o.GetType();
foreach (PropertyInfo pi in t.GetProperties())
{
    IEnumerable<NoHtmlOutput> attributes = pi.GetCustomAttributes<NoHtmlOutput>();
    foreach (NoHtmlOutput attribute in attributes)
    {
      Console.WriteLine(attribute);
    }
}

答案 4 :(得分:0)

您可以使用

PropertyInfo::GetCustomAttributes<T>(true)

工作正常,参见示例: https://dotnetfiddle.net/2IhEWH

所以,没有必要使用静态方法

System.Attribute.GetCustomAttributes