C# 创建匿名LINQ Lambda排序表达式

C# 创建匿名LINQ Lambda排序表达式,c#,linq,lambda,C#,Linq,Lambda,如何创建一个基于MyObject属性的sortExpression通用方法,如下所示: void CreateSortedReport(IList<MyObject> list, Expression<Func<MyObject, TSort>> sortExpression, bool ascending = true) { //sort the [list] by sortExpression and by direction; } 或 编辑1

如何创建一个基于MyObject属性的sortExpression通用方法,如下所示:

void CreateSortedReport(IList<MyObject> list, Expression<Func<MyObject, TSort>> sortExpression, bool ascending = true) 
{
    //sort the [list] by sortExpression and by direction;
}

编辑1: 我之所以要求使用泛型方法,是因为有些方法非常相似:

CreateReportSortedByName(myItems) {
    return myItems.OrderBy(x=>x.Name);
}

CreateReportSortedByDate(myItems) {
    return myItems.OrderBy(x=>x.CreateDate);
}

假设
MyObject
是一个具体类型,只需向方法签名添加一个泛型参数(
):

void CreateReport<TSort>(IList<MyObject> list, Expression<Func<MyObject, TSort>> sortExpression, bool ascending = true)

假设
MyObject
是一个具体类型,只需向方法签名添加一个泛型参数(
):

void CreateReport<TSort>(IList<MyObject> list, Expression<Func<MyObject, TSort>> sortExpression, bool ascending = true)

要使用内置排序函数提供就地排序,您需要编写一个实现
IComparer
的类

例如:

class CompareWithDelegate<TOnObject, TSort> : IComparer<TOnObject>
{
    Func<TOnObject, TSort> evaluator;
    IComparer comparer = Comparer.Default;
    bool ascending;
    public CompareWithDelegate(Expression<Func<TOnObject, TSort>> expr, bool ascending = true)
    {
        evaluator = expr.Compile();
        this.ascending = ascending;
    }
    public int Compare(TOnObject left, TOnObject right)
    {
        var leftVal = evaluator(left);
        var rightVal = evaluator(right);
        return (ascending ? 1 : -1) * comparer.Compare(leftVal, rightVal);
    }
}
或者动态编译表达式:

void CreateSortedReport<TSort>(List<MyObject> list, Expression<Func<MyObject, TSort>> sortExpression, bool ascending = true) 
{
    var method = sortExpression.Compile();
    var t = 
        ascending 
        ? list.OrderBy (method)
        : list.OrderByDescending(method);
}
void CreateSortedReport(列表,表达式sortExpression,bool升序=true)
{
var method=sortExpression.Compile();
变量t=
提升
?list.OrderBy(方法)
:list.OrderByDescending(方法);
}

要使用内置排序函数提供就地排序,您需要编写一个实现
IComparer
的类

例如:

class CompareWithDelegate<TOnObject, TSort> : IComparer<TOnObject>
{
    Func<TOnObject, TSort> evaluator;
    IComparer comparer = Comparer.Default;
    bool ascending;
    public CompareWithDelegate(Expression<Func<TOnObject, TSort>> expr, bool ascending = true)
    {
        evaluator = expr.Compile();
        this.ascending = ascending;
    }
    public int Compare(TOnObject left, TOnObject right)
    {
        var leftVal = evaluator(left);
        var rightVal = evaluator(right);
        return (ascending ? 1 : -1) * comparer.Compare(leftVal, rightVal);
    }
}
或者动态编译表达式:

void CreateSortedReport<TSort>(List<MyObject> list, Expression<Func<MyObject, TSort>> sortExpression, bool ascending = true) 
{
    var method = sortExpression.Compile();
    var t = 
        ascending 
        ? list.OrderBy (method)
        : list.OrderByDescending(method);
}
void CreateSortedReport(列表,表达式sortExpression,bool升序=true)
{
var method=sortExpression.Compile();
变量t=
提升
?list.OrderBy(方法)
:list.OrderByDescending(方法);
}

您可以基于内置函数构建扩展方法


您可以基于内置函数构建扩展方法


@DioPhung,如果你在
IList
上操作,你可以用
Func
@sstan替换你的表达式monad:没错,我想在方法内部进行就地排序。@DioPhung,如果你在
IList
上操作,你可以用
Func
替换你的表达式monad@sstan:没错,我想在方法内部进行就地排序。
void CreateSortedReport<TSort>(List<MyObject> list, Func<MyObject, TSort> sortExpression, bool ascending = true) 
{
    var t = 
        ascending 
        ? list.OrderBy (sortExpression)
        : list.OrderByDescending(sortExpression);
}
void CreateSortedReport<TSort>(List<MyObject> list, Expression<Func<MyObject, TSort>> sortExpression, bool ascending = true) 
{
    var method = sortExpression.Compile();
    var t = 
        ascending 
        ? list.OrderBy (method)
        : list.OrderByDescending(method);
}
public static class SortExtension
{
    public static void SortBy<T, TProperty>(this List<T> list, Func<T, TProperty> orderby, bool ascending = true)
    {
        list.Sort(new InnerComparer<T, TProperty>(orderby, ascending));
    }

    class InnerComparer<T, TProperty> : IComparer<T>
    {
        private readonly Func<T, TProperty> _property;
        private readonly int _ascending;

        public InnerComparer(Func<T, TProperty> property, bool ascending)
        {
            _property = property;
            _ascending = ascending ? 1 : -1;
        }

        int IComparer<T>.Compare(T x, T y)
        {
            var p1 = _property(x);
            var p2 = _property(y);

            return _ascending * Comparer<TProperty>.Default.Compare(p1, p2);
        }
    }
}
myObjects.SortBy(o => o.MyProperty);