2017-08-01 5 views
0

Ich muss eine PropertyDescriptorCollection mit allen Eigenschaften erhalten, die mit einem benutzerdefinierten Attribut versehen sind. Das Problem ist, dass TypeDescriptor.GetProperties nur nach einer genauen Übereinstimmung aller Eigenschaften des Attributs filtern kann. Wenn ich also alle Eigenschaften erhalten möchte, egal wie die Attributeigenschaften eingestellt sind, müsste ich alle Möglichkeiten im Filter-Array abdecken. HierGet PropertyDescriptorCollection nach benutzerdefiniertem Attribut gefiltert

ist der Code für meine Attribué:

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

Und eine Klasse mit verzierten Eigenschaften:

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

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

Und Haupt:

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(); 
} 

Bisher war die einzige Möglichkeit, habe es geschafft, ist der dritte Versuch, ich frage mich, ob es einen intuitiveren und eleganteren Weg gibt.

Die Ausgabe ist die folgende: enter image description here Wie Sie sehen können, kann ich nur schaffen, beide Eigenschaften mit dem letzten Versuch zu erhalten.

Vielen Dank im Voraus

Antwort

1

ich nicht wirklich sicher bin, dass ich das Problem verstehen ... Sie wollen alle Eigenschaften, die ein bestimmtes Attribut unabhängig von diesem Attribute Wert?

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

Das Problem mit Ihrer Lösung ist, dass Sie die Informationen mit 'PropertyInfo []' abrufen. Ich muss PropertyDescriptorCollection verwenden, da ich PropertyDescriptor für jede Eigenschaft benötige, die die Bedingung erfüllt. – taquion

+0

Type.GetProperties ruft ein Array von PropertyInfo ab – taquion

+0

Sie haben Recht. Hat meinen Beitrag bearbeitet. Sie können den übereinstimmenden Deskriptor aus der Sammlung abrufen, die Sie in Ihrem Code durchlaufen. Aber abhängig davon, wie oft Sie diese Funktion aufrufen, sollten Sie beide Benchmarks durchführen, was die Aufgabe besser macht ... – Michael

Verwandte Themen