如何将OrderBy(),Where()等作为参数传递给集合

时间:2015-08-28 13:55:25

标签: c# linq

我有以下代码:

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的参数,以便根据作为参数传递的函数处理集合?

感谢。

4 个答案:

答案 0 :(得分:3)

你可以这样做:

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()

答案 1 :(得分:1)

它们具有不同的签名,编译器必须始终知道返回的类型是什么。除非您希望使用明确投射并在此过程中损坏自己或使用反思更好地工作,否则我建议您进一步考虑您尝试实现的目标,而不是考虑实现它的更好解决方案。

答案 2 :(得分:1)

当然,你可以,非常简单:

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)

答案 3 :(得分:1)

你可以这样做:

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;
}