2010-07-21 6 views
6

J'ai créé un attribut personnalisé pour décorer un certain nombre de classes que je veux interroger au moment de l'exécution:Attribut Héritage et réflexion

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)] 
public class ExampleAttribute : Attribute 
{ 
    public ExampleAttribute(string name) 
    { 
     this.Name = name; 
    } 

    public string Name 
    { 
     get; 
     private set; 
    } 
} 

Chacune de ces classes proviennent d'une classe de base abstraite:

[Example("BaseExample")] 
public abstract class ExampleContentControl : UserControl 
{ 
    // class contents here 
} 

public class DerivedControl : ExampleContentControl 
{ 
    // class contents here 
} 

Ai-je besoin de mettre cet attribut sur chaque classe dérivée, même si je l'ajoute à la classe de base? L'attribut est marqué comme héritable, mais lorsque je fais la requête, je ne vois que la classe de base et non les classes dérivées.

De another thread:

var typesWithMyAttribute = 
    from a in AppDomain.CurrentDomain.GetAssemblies() 
    from t in a.GetTypes() 
    let attributes = t.GetCustomAttributes(typeof(ExampleAttribute), true) 
    where attributes != null && attributes.Length > 0 
    select new { Type = t, Attributes = attributes.Cast<ExampleAttribute>() }; 

Merci, WTS

Répondre

3

Je couru votre code tel qu'il est, et a obtenu le résultat suivant:

{ Type = ConsoleApplication2.ExampleContentControl, Attributes = ConsoleApplication2.ExampleAttribute[] } 
{ Type = ConsoleApplication2.DerivedControl, Attributes = ConsoleApplication2.ExampleAttribute[] } 

Il semble fonctionner ... Tu es sûr que quelque chose ne va pas?

+0

Essayez de placer une classe dérivée dans un autre projet en vous référant au premier. Si je place la classe dérivée dans le même espace de noms que la base, cela fonctionne. –

+0

Eh bien, à moitié compris - les autres assemblys n'étaient pas encore chargés lors de l'appel de la requête LINQ. Je suppose que la question devient alors, "comment puis-je obtenir tous les assemblages qui sont associés à mon exécutable (c'est-à-dire, que dois-je remplacer l'appel AppDomain.CurrentDomain.GetAssemblies() avec)?" –

+0

Bien, cela a du sens ... vous devez trouver un moyen de forcer une charge sur tous les assemblages qui peuvent avoir de l'importance. Cela dépend vraiment de la structure de votre application. Si, par exemple, tous vos assemblys sont chargés à partir du dossier où l'application s'exécute, vous pouvez parcourir et forcer un chargement. Si vous faites quelque chose d'exotique, comme rediriger les charges d'assemblage ... c'est plus compliqué. Si vous savez à l'avance quels assemblages vous attendez, alors la chose la plus simple est simplement de faire référence à un type dans chacun de ces assemblages. –