2017-08-01 4 views
0

Je dois obtenir un PropertyDescriptorCollection avec toutes les propriétés qui sont décorées avec un attribut personnalisé. Le problème est que TypeDescriptor.GetProperties ne peut filtrer que par une correspondance exacte de toutes les propriétés de l'attribut, donc si je veux obtenir toutes les propriétés, peu importe comment les propriétés de l'attribut sont définies, je devrais couvrir toutes les possibilités du tableau de filtres.Get PropertyDescriptorCollection filtré par l'attribut personnalisé

Voici le code pour mon ATTRIBUÉS:

[AttributeUsage(AttributeTargets.Property)] 
class FirstAttribute : Attribute 
{ 
    public bool SomeFlag { get; set; } 
} 

Et une classe avec des propriétés décorées:

class Foo 
{ 
    [First] 
    public string SomeString { get; set; } 

    [First(SomeFlag = true)] 
    public int SomeInt { get; set; } 
} 

Et principaux:

static void Main(string[] args) 
{ 
    var firstPropCollection = TypeDescriptor.GetProperties(typeof(Foo), new Attribute[] {new FirstAttribute()}); 
    Console.WriteLine("First attempt: Filtering by passing an array with a new FirstAttribute"); 
    foreach (PropertyDescriptor propertyDescriptor in firstPropCollection) 
    { 
     Console.WriteLine(propertyDescriptor.Name); 
    } 

    Console.WriteLine(); 
    Console.WriteLine("Second attempt: Filtering by passing an an array with a new FirstAttribute with object initialization"); 
    var secondPropCollection = TypeDescriptor.GetProperties(typeof(Foo), new Attribute[] { new FirstAttribute {SomeFlag = true} }); 
    foreach (PropertyDescriptor propertyDescriptor in secondPropCollection) 
    { 
     Console.WriteLine(propertyDescriptor.Name); 
    } 

    Console.WriteLine(); 
    Console.WriteLine("Third attempt: I am quite ugly =(... but I work!"); 
    var thirdCollection = TypeDescriptor.GetProperties(typeof(Foo)).Cast<PropertyDescriptor>() 
     .Where(p => p.Attributes.Cast<Attribute>().Any(a => a.GetType() == typeof(FirstAttribute))); 
    foreach (PropertyDescriptor propertyDescriptor in thirdCollection) 
    { 
     Console.WriteLine(propertyDescriptor.Name); 
    } 

    Console.ReadLine(); 
} 

Jusqu'à présent, la seule façon l'ai fait fonctionner est la troisième tentative, je me demande s'il y a une manière plus intuitive et élégante.

La sortie est la suivante: enter image description here Comme vous pouvez le voir, je ne parviens à obtenir les deux propriétés qu'avec la dernière tentative.

Merci à l'avance

Répondre

1

Je ne suis pas vraiment sûr que je comprends le problème ... Vous voulez que toutes les propriétés qui ont un attribut spécifique quel que soit cet attribut valeur?

class Program 
{ 
    static void Main(string[] args) 
    { 
     var props = typeof(Foo).GetProperties(); 
     var filtered = props 
      .Where(x => x.GetCustomAttributes(typeof(FirstAttribute), false).Length > 0) 
      .ToList(); 
     var propertyDescriptor = TypeDescriptor.GetProperties(typeof(Foo)) 
      .Find(filtered[0].Name, false); 
    } 
} 
class Foo 
{ 
    [First] 
    public string SomeString { get; set; } 

    [First(SomeFlag = true)] 
    public int SomeInt { get; set; } 
} 
[AttributeUsage(AttributeTargets.Property)] 
class FirstAttribute : Attribute 
{ 
    public bool SomeFlag { get; set; } 
} 
+0

Le problème avec votre solution est que vous récupérez l'information en utilisant 'PropertyInfo []'. Je dois utiliser PropertyDescriptorCollection car j'ai besoin de PropertyDescriptor pour chaque propriété correspondant à la condition. – taquion

+0

Type.GetProperties récupère un tableau de PropertyInfo – taquion

+0

Vous avez raison. Edité mon message. Vous pouvez obtenir le descripteur correspondant de la collection que vous itérez dans votre code. Mais en fonction de la fréquence à laquelle vous appelez cette fonction, vous devriez comparer les deux fonctions qui font le mieux le travail ... – Michael