C#基于另一个List字符串对类属性列表进行排序

时间:2016-02-23 01:56:26

标签: c# sorting reflection

我使用反射遍历属性列表并为表格单元格分配该值。循环的我的类属性被分配给错误的列(标题)。

如何根据标题列表对dataList属性名称进行排序?它们的名字都是一样的。我宁愿这样做,也不愿基于属性排序标题列表。

dataList类型将始终是具有属性的类。

public void SetTableStrong<T>(List<T> dataList, List<string> header)
{       
    // Define our columns
    Column c = null;
    foreach (var item in header)
    {
        c = table.addTextColumn(item);
        c.horAlignment = Column.HorAlignment.CENTER;
    }

    // Initialize Your Table
    table.initialize();
    table.data.Clear();

    foreach (var item in dataList.Select((value, index) => new { value, index }))
    {
        Datum d = Datum.Body(item.index.ToString());

        //Property set to wrong header because they are not sorted to the same as headers.
        foreach (var property in item.value.GetType().GetProperties())
        {
            var value = property.GetValue(item.value, null);

            if (value == null)
                continue;

            d.elements.Add(value.ToString());
        }
        table.data.Add(d);
    }

    // Draw Your Table
    table.startRenderEngine();
}

2 个答案:

答案 0 :(得分:2)

一种方法是首先将所有属性添加到Dictionary<string,string>,然后循环列,并从字典中选择相应的值:

var propValueByName = item
    .value
    .GetType()
    .GetProperties()
    .Select(p => new {
        p.Name
    ,   Val = p.GetValue(item.value, null)
    }).Where(p => p.Val != null)
    .ToDictionary(p => p.Name, p => p.Val.ToString());

现在循环列,并将propValueByName[columnName]添加到d.elements

foreach (var columnName : header) {
    d.elements.Add(propValueByName[columnName]);
}
table.data.Add(d);

答案 1 :(得分:0)

您可以缓存您的属性,然后按照与标题相同的顺序获取它们。

private static Dictionary<Type, PropertyInfo[]> TypeProperties
    = new Dictionary<Type, PropertyInfo[]>();
public IEnumerable<PropertyInfo> GetTypeProperties<T>()
{
    Type type = typeof(T);
    PropertyInfo[] properties;
    if (!TypeProperties.TryGetValue(type, out properties))
        TypeProperties.Add(type, properties = type.GetProperties());
    return properties;
}

/* Fixed excerpt from your code */

var properties = GetTypeProperties<T>();
foreach (var hdr in header)
{
    var property = properties.FirstOrDefault(p => p.PropertyName == hdr);
    if (property != null)
    {
        var value = property.GetValue(item.value, null);
        if (value==null) //Doesn't this also mess the order?
            continue;
        d.elements.Add(value.ToString());
    }
}
table.data.Add(d);