将lambda表达式作为参数传递给方法

本文关键字:参数传递 方法 lambda 表达式 | 更新日期: 2023-09-27 17:54:30

这似乎是一个常见的需求,但我找不到一个解决方案。

我有一个方法,将OrderBy一个集合取决于传递给它的参数。

我想传递一个'OrderBy'的内容给方法,但是不知道怎么做。

What I've try

我尝试过一个字符串开关(即,如果你传递'Name',它会击中按名称订购的case),但这感觉'hacky'和不必要的。

我知道这是类似Func<TEntity, TResult>的东西,但我不能完全破解。

伪代码:

GetOrderedCollection([NOT SURE] orderBy)
{
  return collection.OrderBy(orderBy);
}

将lambda表达式作为参数传递给方法

OrderBy是一个扩展方法,具有以下签名:

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector
)

(来源:https://msdn.microsoft.com/it-it/library/bb534966%28v=vs.110%29.aspx)

所以你的方法需要一个Func作为它的参数,其中TSource是List类型,TKey是lambda返回的类型。例如:

public void Method<TSource, TKey>(List<TSource> list, Func<TSource, TKey> func)
        {
            ...
            IOrderedEnumerable<TSource> orderedEnumerable = list.OrderBy(func);
        }
编辑:

我还注意到,在你的示例代码中,你声明你的方法为void,但然后你试图返回一个IOrderedEnumerable。如果您想要返回有序的集合,您的方法至少需要有一个IEnumerable类型(但这会破坏排序的目的,因为IEnumerable不能保证顺序)。更可能的实现是返回List<TSource>并调用list.OrderBy(func).ToList()

在最一般的形式中,您的方法需要看起来像:

IOrderedEnumerable<T1> GetOrderedCollection<T1, T2>(IEnumerable<T1> collection, Func<T1, T2> orderBy)
{
    return collection.OrderBy(orderBy);
}

T1为列表中项目的类型,T2为您想要排序的T1的属性类型。

满足您的要求吗?

    static void Main(string[] args) {           
        var objects = new List<Test>();
        GetOrderedCollection(objects, x => x.Name);
    }
    class Test {
        public string Name { get; set; }
    }
    static IEnumerable<TEntity> GetOrderedCollection<TEntity>(IEnumerable<TEntity> objects, Func<TEntity, object> orderBy) {
        return objects.OrderBy(orderBy);
    }

是的,你正在寻找一个Func<TEntity, TResult> orderingFunc。重要的是输出(TResult)是IComparable,以便OrderBy函数可以正确地对结果进行排序。

这样就可以了:

public void OrderByDynamic(Func<Model, object> orderByFunc)
{
    collection = collection.OrderBy(orderByFunc); //don't forget to assign the return value
}

你可以像普通的lambda函数那样调用它:

OrderByDynamic(m => m.SortObj); //as long as this property/return value is IComparable

一个演示这个想法的。net Fiddle

参数必须为FuncAction