Каков наилучший способ динамического доступа к свойствам для сортировки списка? - PullRequest
0 голосов
/ 21 июня 2011

Я заполняю виртуальный просмотр списка содержимым списка объектов. Это элемент управления списком winforms, работающий на .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);
}

Я генерирую элементы viewview в обработчике listView1_RetrieveVirtualItem:

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 при нажатии на столбец, проверив тип свойства для этого столбца. Нединамический способ сделать это, вероятно, заключался бы в написании оператора long 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);
    });
}

Это работает нормально, но я читал, что производительность с использованием отражения может быть медленной, и что есть лучшие способы сделать это. Я хотел бы улучшить свой код. Как мне динамически обращаться к неизвестным свойствам объекта во время выполнения, чтобы отсортировать их?

1 Ответ

0 голосов
/ 21 июня 2011

, если вы можете получить имя столбца, попробуйте использовать Dynamic LINQ (http://aonnull.blogspot.com/2010/08/dynamic-sql-like-linq-orderby-extension.html)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...