2010-02-09 15 views
5

Estoy trabajando en C# .NEt 2.0. Tengo una clase, digamos X con muchas propiedades. Cada propiedad tiene un atributo personalizado, un interger, que planeé usar para especificar su orden en la matriz final.¿Cómo ordeno una lista genérica basada en un atributo personalizado?

Usando la reflexión Leo todas las propiedades y agrupo los valores y los coloco en una lista genérica de propiedades. Esto funciona y puedo agarrar los valores. Pero el plan fue CLASIFICAR la lista, basado en el atributo personalizado colocado en cada propiedad, y finalmente leyó los valores de propiedad, ya ordenados, en una cadena.

Respuesta

11

Digamos que usted tenía la siguiente definición de atributo

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

Usted podría utilizar el siguiente código para extraer las propiedades de un tipo en el orden establecido. Asumiendo por supuesto que todos tienen este atributo Solución

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 Estilo

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

Su respuesta trabaja para C# 3 + y al que se LINQ no está disponible en marco 2.0 – Argons

+0

@Argons, leyó la derecha más allá del 2.0 restricción. ¿Actualizará – JaredPar

+0

si quiero obtener solo atributos con el atributo Ordenar? ¿Y no es el código que falta la validación de que no hay dos propiedades con el mismo orden? – gdoron

Cuestiones relacionadas