动态访问属性以排序列表的最佳方法是什么?

时间:2011-06-21 06:13:09

标签: c# list sorting reflection properties

我使用对象列表的内容填充虚拟列表视图。它是一个winforms listview控件,运行在.Net 3.5上。我正在从对象的公共属性动态生成列。为此,我在表单的构造函数中使用了一个循环:

properties = typeof(MyCustomObject).GetProperties().ToArray();
foreach (PropertyInfo property in properties)
{
    ColumnHeader ch = new ColumnHeader();
    ch.Text = property.Name;
    listView1.Columns.Add(ch);
}

我在listView1_RetrieveVirtualItem处理程序中生成listviewitems:

MyCustomObject myCustomObject = myCustomObjects[e.ItemIndex];
ListViewItem item = new ListViewItem(myCustomObject.ID, 0);
foreach (PropertyInfo property in properties)
{
    var propvalue = property.GetValue(myCustomObject, null);
    if (propvalue == null)
        item.SubItems.Add("");
    else
        item.SubItems.Add(propvalue.ToString());
}

通过检查该列的属性类型,单击列时,我需要对listView1_ColumnClicked处理程序中的对象列表进行排序。执行此操作的非动态方法可能是编写处理每列的if if else语句(或switch语句):

if (sortColumn == 1)
{
    myCustomObjects.Sort(delegate(MyCustomObject o1, MyCustomObject o2)
    {
        DateTime t1 = o1.FirstDate ?? DateTime.MinValue;
        DateTime t2 = o2.FirstDate ?? DateTime.MinValue;
        return t1.CompareTo(t2);
    });
}
else if (sortColumn == 2)
{
    myCustomObjects.Sort(delegate(MyCustomObject o1, MyCustomObject o2)
    {
        DateTime t1 = o1.SecondDate ?? DateTime.MinValue;
        DateTime t2 = o2.SecondDate ?? DateTime.MinValue;
        return t1.CompareTo(t2);
    });
}
else if (sortColumn == 3)
{
    myCustomObjects.Sort(delegate(MyCustomObject o1, MyCustomObject o2)
    {
        return e1.FirstName.CompareTo(e2.FirstName);
    });
}
else if (sortColumn == 4)
{
    myCustomObjects.Sort(delegate(MyCustomObject o1, MyCustomObject o2)
    {
        return e1.LastName.CompareTo(e2.LastName);
    });
}
else
    // and so on, for each property...

这显然会复制包含相同数据类型的列的代码。我已使用属性类型代码来替换它,以确定如何对列进行排序:

PropertyInfo property = properties[sortColumn];
Type type = property.PropertyType;
if (type == typeof(DateTime))
{
    myCustomObjects.Sort(delegate(MyCustomObject o1, MyCustomObject o2)
    {
        DateTime t1 = (DateTime)property.GetValue(o1, null);
        DateTime t2 = (DateTime)property.GetValue(o2, null);
        return t1.CompareTo(t2);
    });
}
else if (type == typeof(int))
{
    myCustomObjects.Sort(delegate(MyCustomObject o1, MyCustomObject o2)
    {
        int n1 = (int)property.GetValue(o1, null);
        int n2 = (int)property.GetValue(o2, null);
        return n1.CompareTo(n2);
    });
}
else if (type == typeof(string))
{
    myCustomObjects.Sort(delegate(MyCustomObject o1, MyCustomObject o2)
    {
        string s1 = (string)property.GetValue(o1, null);
        string s2 = (string)property.GetValue(o2, null);
        return s1.CompareTo(s2);
    });
}

这工作正常,但我已经读过使用反射的性能可能很慢并且有更好的方法来执行此操作。我想改进我的代码。我应该如何在运行时动态访问未知对象属性以对它们进行排序?

1 个答案:

答案 0 :(得分:0)

如果你能获得列名,请尝试使用Dynamic LINQ(http://aonnull.blogspot.com/2010/08/dynamic-sql-like-linq-orderby-extension.html)