其他分享
首页 > 其他分享> > CodeGo.net>为通用列表创建排序功能

CodeGo.net>为通用列表创建排序功能

作者:互联网

我有一种按对象字段对通用列表进行排序的方法:

public static IQueryable<T> SortTable<T>(IQueryable<T> q, string sortfield, bool ascending)
{
    var p = Expression.Parameter(typeof(T), "p");

    if (typeof(T).GetProperty(sortfield).PropertyType == typeof(int?))
    {
        var x = Expression.Lambda<Func<T, int?>>(Expression.Property(p, sortfield), p);
        if (ascending)
            q = q.OrderBy(x);
        else
            q = q.OrderByDescending(x);
    }
    else if (typeof(T).GetProperty(sortfield).PropertyType == typeof(int))
    {
        var x = Expression.Lambda<Func<T, int>>(Expression.Property(p, sortfield), p);
        if (ascending)
            q = q.OrderBy(x);
        else
            q = q.OrderByDescending(x);
    }
    else if (typeof(T).GetProperty(sortfield).PropertyType == typeof(DateTime))
    {
        var x = Expression.Lambda<Func<T, DateTime>>(Expression.Property(p, sortfield), p);
        if (ascending)
            q = q.OrderBy(x);
        else
            q = q.OrderByDescending(x);
    }
    // many more for every type
    return q;
}

有什么办法可以将这些ifs折叠为一个通用语句?
主要的问题是
Expression.Lambda Func T,int>
我不确定如何通用地编写它.

解决方法:

如果将Queryable.OrderBy扩展为其定义,则不必使用Expression.Lambda的泛型重载:

public static IQueryable<T> SortTable<T>(
    IQueryable<T> q, string sortfield, bool ascending)
{
    var p = Expression.Parameter(typeof(T), "p");
    var x = Expression.Lambda(Expression.Property(p, sortfield), p);

    return q.Provider.CreateQuery<T>(
               Expression.Call(typeof(Queryable),
                               ascending ? "OrderBy" : "OrderByDescending",
                               new Type[] { q.ElementType, x.Body.Type },
                               q.Expression,
                               x));
}

标签:generics,c
来源: https://codeday.me/bug/20191210/2099431.html