Построение лямбда-выражения для общего списка

У меня есть метод через 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);
Другие вопросы по тегам