Построение лямбда-выражения для общего списка
У меня есть метод через ObjectDataSource кормит вид сетки и позволяет сортировать по столбцу с помощью лямбда-выражений:
public IList<UsersEntity> GetUsers()
{
return new List<UsersEntity>(new[] {
new UsersEntity{ UsrId =1, UsrName="Luis" },
new UsersEntity{ UsrId = 2, UsrName = "Pablo"} });
}
public IList<UsersEntity> GetUsers(string OrderBy)
{
string[] ordParts = OrderBy.Split(' ');
string ordBy = ordParts[0];
string direction = "ASC";
if (2 == ordParts.Length)
direction = "DESC";
//Get Unsorted List
List<UsersEntity> Lista = (List<UsersEntity>)GetUsers();
//Function to order
Func<UsersEntity, object> myFunct = null;
myFunct = (usr) => {
if ("UsrId" == ordBy) return usr.UsrId;
else return usr.UsrName;
};
//sort list
if ("ASC" == direction)
return Lista.OrderBy(myFunct).ToList();
else
return Lista.OrderByDescending(myFunct).ToList();
}
Но я хочу что-то более функциональное, то, что работает для всех типов списков и не требует добавления большого количества кода. Поэтому я написал эту функцию, которую я не могу выполнить:
public class OrdenarEntidades<T>
{
public static IEnumerable<T> SortList(IEnumerable<T> Listado, string OrderByArg)
{
string[] arrOrderBy = OrderByArg.Split(' ');
string orderBy = arrOrderBy[0];
string direction = "ASC";
if (2 == arrOrderBy.Length)
direction = "DESC";
foreach (PropertyInfo pInfo in typeof(T).GetProperties())
{
if (orderBy == pInfo.Name)
{
Type tipDev = pInfo.PropertyType;
Func<T, tipDev> MyFunct = (Entity) => { pInfo.GetValue(Entity, null); };
if ("ASC" == direction)
Listado.OrderBy(MyFunct);
else
Listado.OrderBy(MyFunct);
}
}
return Listado;
}
}
Я знаю, что этот код не компилируется, однако выражает идею того, чего я хочу достичь.
Marc Gravell дает приближение к тому, что я ищу ( здесь), но не знаю, как адаптировать его к моему коду
Заранее большое спасибо.
1 ответ
Вам нужно что-то вроде
public class OrdenarEntidades<T>
{
public static IOrderedEnumerable<T> SortList(IEnumerable<T> Listado, params Func<T, object>[] orders)
{
if(orders.Length == 0)
return Listado;
IOrderedEnumerable<T> result = Listado.OrderBy(orders[0]);
for(int i = 1; i < orders.Length; ++i)
result = result.ThenBy(orders[i]);
return result;
}
}
Это поддерживает только ВЕРНУТЬ заказ. Чтобы разрешить в обоих направлениях Func<T, object>
в классе со свойством direction, на основе которого OrderBy
или же OrderByDescending
называется.
Функция может быть вызвана так
var usersSorted = OrdenarEntidades<UserEntity>.SortList(users, user=>user.UsrId, user=>user.UsrName);