c# - Better way to Sort a List by any property -
my method receives datatables parameters sort table column clicked. call method controller of each page list. i'm looking better way generic method types: string, int, decimal, double, bool (nullable or not). can't find it.
my current code:
public list<t> orderinglist<t>(list<t> list, datatablesparam model) { var icolumn = model.order.firstordefault().column; var property = typeof(t).getproperty(model.columns.toarray()[icolumn].data); var param = expression.parameter(typeof(t)); var final = expression.property(param, property); var isdirasc = model.order.firstordefault().dir.equals("asc"); if (property.propertytype == typeof(string)) { var lambda = expression.lambda<func<t, string>>(final, param).compile(); return isdirasc ? list.orderby(lambda).tolist() : list.orderbydescending(lambda).tolist(); } else if (property.propertytype == typeof(int)) { var lambda = expression.lambda<func<t, int>>(final, param).compile(); return isdirasc ? list.orderby(lambda).tolist() : list.orderbydescending(lambda).tolist(); } else if (property.propertytype == typeof(bool)) { var lambda = expression.lambda<func<t, bool>>(final, param).compile(); return isdirasc ? list.orderby(lambda).tolist() : list.orderbydescending(lambda).tolist(); } else if (property.propertytype == typeof(decimal)) { var lambda = expression.lambda<func<t, decimal>>(final, param).compile(); return isdirasc ? list.orderby(lambda).tolist() : list.orderbydescending(lambda).tolist(); } else if (property.propertytype == typeof(double)) { var lambda = expression.lambda<func<t, double>>(final, param).compile(); return isdirasc ? list.orderby(lambda).tolist() : list.orderbydescending(lambda).tolist(); } return list; }
i want this: (but code doesn't work)
public list<t> orderinglist<t>(list<t> list, datatablesparam model) { var icolumn = model.order.firstordefault().column; var property = typeof(t).getproperty(model.columns.toarray()[icolumn].data); var param = expression.parameter(typeof(t)); var final = expression.property(param, property); var isdirasc = model.order.firstordefault().dir.equals("asc"); var lambda = expression.lambda<func<t, dynamic>>(final, param).compile(); return isdirasc ? list.orderby(lambda).tolist() : list.orderbydescending(lambda).tolist(); }
you can call enumerable.orderby
method using reflection. way, don’t have know type @ compile-time. that, need method, , create generic method using property’s type:
private ienumerable<t> sort<t> (list<t> list, string propertyname) { methodinfo orderbymethod = typeof(enumerable).getmethods().first(mi => mi.name == "orderby" && mi.getparameters().length == 2); propertyinfo pi = typeof(t).getproperty(propertyname); methodinfo orderby = orderbymethod.makegenericmethod(typeof(t), pi.propertytype); parameterexpression param = expression.parameter(typeof(t)); delegate accessor = expression.lambda(expression.property(param, pi), param).compile(); return (ienumerable<t>)orderby.invoke(null, new object[] { lst, accessor }); }
note abstracted out stuff model keep method generic enough. can sort property on list specifying property name. original method this:
public list<t> orderinglist<t>(list<t> list, datatablesparam model) { var icolumn = model.order.firstordefault().column; string propertyname = model.columns.toarray()[icolumn].data; return sort(list, propertyname).tolist(); }
Comments
Post a Comment