2010-02-09 10 views
5

Ich arbeite in C# .NEt 2.0. Ich habe eine Klasse, sagen wir X mit vielen Eigenschaften. Jede Eigenschaft hat ein benutzerdefiniertes Attribut, ein Interger, das ich verwenden wollte, um ihre Reihenfolge im endgültigen Array anzugeben.Wie sortiere ich eine generische Liste basierend auf einem benutzerdefinierten Attribut?

Mit Reflektion durchlese ich alle Eigenschaften und gruppiere die Werte und lege sie in eine generische Liste von Eigenschaften. Das funktioniert und ich kann die Werte greifen. Aber der Plan war SORTIEREN Sie die Liste, basierend auf dem benutzerdefinierten Attribut, das auf jeder Eigenschaft platziert wird, und lesen Sie schließlich die bereits bestellten Propery-Werte in eine Zeichenfolge aus.

Antwort

11

Lassen Sie uns sagen Sie das folgende Attribut Definition hatte

public class SortAttribute : Attribute { 
    public int Order { get; set; } 
    public SortAttribute(int order) { Order = order; } 
} 

Sie könnten den folgenden Code verwenden, in sortierter Reihenfolge auf eine Art, die Eigenschaften zu ziehen. Unter der Annahme, natürlich alles, was sie haben dieses Attribut

public IEnumerable<object> GetPropertiesSorted(object obj) { 
    Type type = obj.GetType(); 
    List<KeyValuePair<object,int>> list = new List<KeyValuePair<object,int>>(); 
    foreach (PropertyInfo info in type.GetProperties()) { 
    object value = info.GetValue(obj,null); 
    SortAttribute sort = (SortAttribute)Attribute.GetCustomAttribute(x, typeof(SortAttribute), false); 
    list.Add(new KeyValuePair<object,int>(value,sort.Order)); 
    } 
    list.Sort(delegate (KeyValuePair<object,int> left, KeyValuePair<object,int> right) { left.Value.CompareTo right.Value; }); 
    List<object> retList = new List<object>(); 
    foreach (var item in list) { 
    retList.Add(item.Key); 
    } 
    return retList; 
} 

LINQ-Art-Lösung

public IEnumerable<string> GetPropertiesSorted(object obj) { 
    var type = obj.GetType(); 
    return type 
    .GetProperties() 
    .Select(x => new { 
     Value = x.GetValue(obj,null), 
     Attribute = (SortAttribute)Attribute.GetCustomAttribute(x, typeof(SortAttribute), false) }) 
    .OrderBy(x => x.Attribute.Order) 
    .Select(x => x.Value) 
    .Cast<string>(); 
} 
+2

Ihre Antwort arbeitet für C# 3 + und Linq wich ist im Rahmen nicht verfügbar 2.0 – Argons

+0

@Argons, lesen Sie rechts vorbei an der 2.0 Beschränkung. Wird update – JaredPar

+0

Wenn ich nur Attribute mit Sort-Attribut erhalten möchte? Und fehlt der Code nicht, dass es nicht zwei Eigenschaften in der gleichen Reihenfolge gibt? – gdoron

Verwandte Themen