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
}
いいえ、属性は継承されます。
親の宣言を調べないのはGetCustomAttributes()
メソッドです。指定されたメンバーに適用されている属性のみを調べます。 ドキュメントから :
備考
このメソッドは、プロパティとイベントの継承パラメーターを無視します。プロパティとイベントの属性の継承チェーンを検索するには、Attribute .. ::。GetCustomAttributesメソッドの適切なオーバーロードを使用します。
次のように、PropertyInfo.GetCustomAttributes(...)を呼び出す代わりに、静的メソッドSystem.Attribute.GetCustomAttributes(pi、...)を呼び出す必要があります。
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);
オーバーライドするメソッドにも属性がある場合にのみ発生するようです。
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
これが私の試みです。これはMemberInfo
の拡張メソッドであり、継承階層を手動でウォークアップします。これは、動的プロキシと互換性があるようです...少なくとも城によって作成されたホースはとにかく、すべてのプロキシライブラリと互換性があると思います。
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);
}
}
使用できます
PropertyInfo::GetCustomAttributes<T>(true)
正常に動作します。例を参照してください: https://dotnetfiddle.net/2IhEWH
したがって、静的メソッドを使用する必要はありません
System.Attribute.GetCustomAttributes