如何传递OrderBy(), Where()等,作为处理集合的参数
本文关键字:处理 集合 参数 Where 何传递 OrderBy | 更新日期: 2023-09-27 18:10:11
我有以下代码:
class Program
{
static void Main(string[] args)
{
List<int> li = new List<int>() { 1,2,3,4,5,6,7,8,9,10 };
ProcessCollection(li, x => x);
}
static IEnumerable<TSource> ProcessCollection<TSource,TResult>(IEnumerable<TSource> c, Func<TSource, TResult> lambdaexp)
{
return c.OrderBy(lambdaexp);
}
}
如您所见,它接受一个集合,处理它并返回新集合。当前通过OrderBy()
扩展方法处理集合。
我想扩展这个函数,这样它就可以接受另一个(第三个)参数作为函数,并将这个函数应用于作为第一个参数传递的集合。到目前为止,我一直在尝试用Func<>
和Action<>
的组合,但我不能算出来。我还是初学者。
是否有可能定义ProcessCollection
的参数,以便它根据作为参数传递的函数处理集合?
谢谢。
你可以这样做:
static IEnumerable<TElemType> Process<TElemType>(IEnumerable<TElemType> source,
params Func<IEnumerable<TElemType>, IEnumerable<TElemType>>[] funcs)
{
foreach(var func in funcs)
source = func(source);
return source;
}
并像这样使用:
List<int> li = new List<int>() { 1,2,3,4,5,6,7,8,9,10 };
Process(li, x => x.OrderBy(y => y), x => x.Reverse());
但我真的不确定为什么这样做比直接做更好:
li.OrderBy(y => y).Reverse()
它们具有不同的签名,编译器必须始终知道返回类型是什么。除非您想使用显式强制转换并在此过程中损害您自己,或者更好地使用反射,否则我建议您进一步考虑您试图实现的目标,然后考虑更好的解决方案来实现它。
当然可以,这很简单:
static IEnumerable<TResult> ProcessCollection<TSource,TResult>
(IEnumerable<TSource> c, Func<IEnumerable<TSource>, IEnumerable<TResult>> func)
{
return func(c);
}
换句话说,不是传递一个应用于每个元素的函数,而是传递一个转换整个枚举对象的函数。你可以这样调用它,例如:
ProcessCollection(new [] { 1, 2, 3 }, c => c.OrderBy(i => i));
如果你想同时应用更多的转换,只需将它们链接在一起(这就是LINQ,真的):
ProcessCollection(new [] { 1, 2, 3 }, c => c.Select(i => i.ToString()).OrderBy(i => i));
当然,这没什么用。它所做的事情与简单地执行
完全相同new [] { 1, 2, 3 }.Select(i => i.ToString()).OrderBy(i => i);
首先是。即使你在你的ProcessCollection
方法中做一些实际的处理,你通常只使用这样的东西:
new [] { 1, 2, 3 }.Process().Select(i => i.ToString()).OrderBy(i => i)
你可以这样做:
void Main(string[] args)
{
List<int> li = new List<int>() { 1,2,3,4,5,6,7,8,9,10 };
Func<int, bool> whereFilter = x => x % 2 == 0;
Func<int, string> orderByClause = x => x.ToString();
ProcessCollection(li, whereFilter, orderByClause); // 10, 2, 4, 6, 8
}
static IEnumerable<TSource> ProcessCollection<TSource, TResult>(
IEnumerable<TSource> source,
Func<TSource, bool> whereFilter = null,
Func<TSource, TResult> orderByClause = null)
{
if (whereFilter != null) source = source.Where(whereFilter);
if (orderByClause != null) source = source.OrderBy(orderByClause);
return source;
}