0

I have a Table class to which I pass a generic list of objects called data. Since the objects stored in the list can be of various type I implemented the following Table class

public class Table<T>
{
   private List<T> _data;

   public Table(List<T> data)
   {
       _data = data;
       //other constructor stuff
   }
}

The idea is that the Table class will "build" a table listing as colums all the public properties of the T - type object stored in the data. I managed to achieve this by doing _data[0].GetType().GetProperties() to retrieve the properties and to build the columns header. I then implemented a click event on the column titles so that by clicking on it the data would get sorted by this property. Here is where the problem is. I cannot get Linq to sort by the given property since at compile time the type of the object is not known.

I tried with

_data = _data.OrderBy(e => e.GetType().GetProperty("Surname")).ToList<T>();

Where Surname is a property that I know my test object (stored in the _data) has.

I don't get any errors but it seems the instruction to order doesn't do anything. What is wrong? Is there a less convoluted way of doing this? (BTW I'm not using WPF so I guess there is not point in using DataTable).

I found similar questions answered already but in all of them the the T-type of the List was known at compile time.

Thanks for your help.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
Peter
  • 33
  • 4
  • The result of your `OrderBy` expression is just a `PropertyInfo` object, which will be the same for every row, not the _value_ of the property for that row. I've marked a duplicate of an example of dynamic ordering. – D Stanley Mar 27 '23 at 16:24

1 Answers1

0

You can try using PropertyInfo.GetValue:

_data = _data
    .OrderBy(e => e.GetType().GetProperty("Surename").GetValue(e))
    .ToList<T>();

But in general I would recommend to look into tools allowing you to avoiding using reflection. Or at least trying to move the reflection out of the LINQ:

var pi = typeof(T).GetProperty("Surename");
_data = _data
    .OrderBy(e => pi.GetValue(e))
    .ToList<T>();

Or better "caching" it (take a look at one of these answers - one, two).

Guru Stron
  • 102,774
  • 10
  • 95
  • 132