【问题标题】:What is the best way to dynamically access properties for sorting a list?动态访问属性以对列表进行排序的最佳方法是什么?
【发布时间】:2011-09-19 05:59:01
【问题描述】:

我正在使用对象列表的内容填充虚拟列表视图。它是一个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 then 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);
    });
}

这工作正常,但我读到使用反射的性能可能会很慢,并且有更好的方法可以做到这一点。我想改进我的代码。我应该如何在运行时动态访问未知对象属性以便对其进行排序?

【问题讨论】:

    标签: c# list sorting reflection properties


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-07
      • 2010-12-16
      • 2018-11-20
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 2014-05-27
      相关资源
      最近更新 更多