none
Klassen mit einem bestimmten Custom Attribut ermitteln RRS feed

  • Frage

  • Hallo Forum,

    ich habe eine Klassen in dem verschiedene Member mit Custom Attributen versehen sind.

    zu einer Klasse lese ich die Attribute wie folgt aus, was auch schön funktioniert. Somit bekomme ich alle Member aus der Klasse "ModelClass" mit mit dem Attribut "TableColumnPropertyAttribute" deklariert wurden

    IEnumerable<TableColumnPropertyAttribute> propAttributes = this.CustomerAttributesTable<ModelClass>();

    private IEnumerable<TableColumnPropertyAttribute> CustomerAttributesTable<T>() { IEnumerable<TableColumnPropertyAttribute> obj = null; obj = typeof(T).GetProperties().SelectMany(p => p.GetCustomAttributes()) .OfType<TableColumnPropertyAttribute>().AsParallel(); return obj; }

    So weit so gut.

    Nun möchte ich aber auch alle Klassen aus meinem Assemby haben, in dem ein Member mit einem bestimmten Custom Attribut deklariert wurde. Also nicht die Member selbst sonder nur die Klassen in dem das Attribut deklariert wurde.

    Danke und Gruß
    Gerhard

    Freitag, 22. Juli 2016 06:02

Antworten

  • Hallo Gerhard,

    Um alle Klassen zu finden, in dem ein Element ein bestimmtes Attribut hat:

            public static IEnumerable<Type> GetClassAttribute<T>(Assembly assembly) where T : Attribute
            {
    
                return assembly.GetTypes().Where(t => t.GetMembers().Where(m => m.GetCustomAttributes<T>().Any()).Any());
            }

    wobei hier nicht zwischen Eigenschaften, Methoden etc. differenziert wird, sondern alle öffentlichen Member getestet werden, siehe GetMembers, falls Du es auf private etc. erweitern willst.

    Dann verwendet z. B. mit einem BrowsableAttribute:

        // Browsable kommt bei Windows Forms häufiger vor ;)
        var assembly = typeof(System.Windows.Forms.Form).Assembly;
        var types = GetClassAttribute<BrowsableAttribute>(assembly);
    
        var count = types.Count();
        Console.WriteLine($"{count}");
        foreach (var type in types)
        {
            Console.WriteLine($"{type}");
        }
    

    Was Deine Methode angeht: So auf Vorrat sollte man AsParallel nicht einbauen, da das unter Umständen Seiteneffekte hat - nicht jeder Folge-Code ist threadsicher. Wenn man es will, sollte man das bei der Verwendung der Methode in einer konkreten Anweisung tun.

    Gruß Elmar

    Freitag, 22. Juli 2016 07:54
    Beantworter

Alle Antworten

  • Hallo Gerhard,

    Um alle Klassen zu finden, in dem ein Element ein bestimmtes Attribut hat:

            public static IEnumerable<Type> GetClassAttribute<T>(Assembly assembly) where T : Attribute
            {
    
                return assembly.GetTypes().Where(t => t.GetMembers().Where(m => m.GetCustomAttributes<T>().Any()).Any());
            }

    wobei hier nicht zwischen Eigenschaften, Methoden etc. differenziert wird, sondern alle öffentlichen Member getestet werden, siehe GetMembers, falls Du es auf private etc. erweitern willst.

    Dann verwendet z. B. mit einem BrowsableAttribute:

        // Browsable kommt bei Windows Forms häufiger vor ;)
        var assembly = typeof(System.Windows.Forms.Form).Assembly;
        var types = GetClassAttribute<BrowsableAttribute>(assembly);
    
        var count = types.Count();
        Console.WriteLine($"{count}");
        foreach (var type in types)
        {
            Console.WriteLine($"{type}");
        }
    

    Was Deine Methode angeht: So auf Vorrat sollte man AsParallel nicht einbauen, da das unter Umständen Seiteneffekte hat - nicht jeder Folge-Code ist threadsicher. Wenn man es will, sollte man das bei der Verwendung der Methode in einer konkreten Anweisung tun.

    Gruß Elmar

    Freitag, 22. Juli 2016 07:54
    Beantworter
  • Hallo Elmar,

    danke für die Zeilen Code, das mit den Klassen auf Basis eines Attributes zur ermitteln ist ja wirklich schon Trickreich. Mein ursprünglicher Code hatte immer zu viel zurückgegeben. Ich vermute das liegt an ".Any()).Any());"

    Das mit dem ".AsParallel()" werde ich mir zu Herzen nehmen.

    Danke und Gruß
    Gerhard

    Freitag, 22. Juli 2016 12:47
  • Hallo Gerhard,

    Any testet darauf, ob in dem Enumerable<T> etwas enthalten ist. Was hier zum einen für das Attribut (ist es vergeben) und zum anderen auf das Ergebnis der verbleibenden MemberInfo Elemente angewendet wird. Wird mindestens ein Element gefunden (Any == true), wird der Type geliefert sonst nicht.

    Man könnte auch etwas wie Count nehmen, nur das ist aufwändiger, weil es die gesamte Menge durchackert.

    Gruß Elmar

    Freitag, 22. Juli 2016 16:18
    Beantworter