我有一个自定义属性,我想应用于我的基本抽象类,以便我可以跳过在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
}
答案 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