2010-02-09 8 views
5

Je travaille dans C# 2.0 .Net. J'ai une classe, disons X avec beaucoup de propriétés. Chaque propriété a un attribut personnalisé, un interger, que j'ai prévu d'utiliser pour spécifier son ordre dans le tableau final. Utilisation de la réflexion J'examine toutes les propriétés et regroupe les valeurs et les place dans une liste générique de propriétés. Cela fonctionne et je peux saisir les valeurs. Mais le plan était TRIER la liste, basé sur l'attribut personnalisé placé sur chaque propriété, et finalement lire les valeurs de propriété, déjà commandées, dans une chaîne.Comment trier une liste générique en fonction d'un attribut personnalisé?

Répondre

11

Disons que vous aviez la définition d'attribut suivant

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

Vous pouvez utiliser le code ci-dessous pour retirer les propriétés sur un type dans l'ordre. En supposant bien sûr, ils ont tous cet 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 style Solution

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

Votre réponse fonctionne pour C# 3 + et Wich LINQ est pas disponible dans le cadre 2.0 – Argons

+0

@Argons, lu à droite après le 2.0 restriction. Mettra à jour – JaredPar

+0

Si je veux obtenir seulement des attributs avec l'attribut de tri? Et le code ne manque-t-il pas la validation qu'il n'y a pas deux propriétés avec le même ordre? – gdoron