c# konstruktor - Vererbung von benutzerdefinierten Attributen auf abstrakte Eigenschaften



mehrere klassen (5)

Nein, Attribute werden vererbt.

Es ist die GetCustomAttributes() -Methode, die keine übergeordneten Deklarationen betrachtet. Es werden nur Attribute betrachtet, die auf das angegebene Element angewendet wurden. Aus den Dokumenten :

Bemerkungen

Diese Methode ignoriert den Parameter erben für Eigenschaften und Ereignisse. Verwenden Sie die entsprechenden Überladungen der Methode Attribut .. ::. GetCustomAttributes, um die Vererbungskette nach Attributen für Eigenschaften und Ereignisse zu durchsuchen.

Ich habe ein benutzerdefiniertes Attribut, das ich auf meine abstrakte Basisklasse anwenden möchte, sodass ich Elemente überspringen kann, die nicht vom Benutzer angezeigt werden müssen, wenn das Element in HTML angezeigt wird. Es scheint, dass die Eigenschaften, die die Basisklasse überschreiben, die Attribute nicht übernehmen.

Überschreibt das Überschreiben von Basiseigenschaften (abstrakt oder virtuell) Attribute, die auf der ursprünglichen Eigenschaft platziert sind?

Aus Attributklasse Definition

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

Aus abstrakter Klasse Definierung

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

Aus der Definition der Betonklasse

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

Von der Klasse, die nach Attribut sucht

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

Sie können verwenden

PropertyInfo::GetCustomAttributes<T>(true)

Das funktioniert gut, siehe Beispiel: https://dotnetfiddle.net/2IhEWH

Daher muss die statische Methode nicht verwendet werden

System.Attribute.GetCustomAttributes

Hier ist mein Versuch. Dies ist eine Erweiterungsmethode in MemberInfo , die die Vererbungshierarchie manuell MemberInfo . Dies scheint mit dynamischen Proxies kompatibel zu sein ... zumindest von Castle, das sowieso von Castle erstellt wurde, also gehe ich davon aus, dass es mit jeder Proxy-Bibliothek kompatibel wäre.

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[] { };
}

Und du würdest es so benutzen.

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

Es sieht so aus, als ob es nur passiert, wenn die überschreibende Methode auch das Attribut besitzt.

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

Sie können jedoch Attribute desselben Typs überschreiben oder zusätzliche Attribute auf die abgeleitete Komponente anwenden. Das folgende Codefragment zeigt ein benutzerdefiniertes Steuerelement, das die von Control geerbte Texteigenschaft überschreibt, indem das in der Basisklasse angewendete BrowsableAttribute-Attribut überschrieben wird. 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

Für ein einzelnes Ergebnis:

if (reader.Read())
{
    Response.Write(reader[0].ToString());
    Response.Write(reader[1].ToString());
}

Für mehrere Ergebnisse:

while (reader.Read())
{
    Response.Write(reader[0].ToString());
    Response.Write(reader[1].ToString());
}




c# reflection attributes abstract-class