C# 以泛型方式传递类型成员以对泛型集合进行操作

C# 以泛型方式传递类型成员以对泛型集合进行操作,c#,linq,generics,collections,anonymous-delegates,C#,Linq,Generics,Collections,Anonymous Delegates,我正在创建一个函数,它将获取一些IEnumerable,进行分组、排序,获取一些前N个元素,并返回这些元素的列表。它以后可能会做更多的工作,这就是为什么我想把它变成一个函数,而不仅仅是直接使用LINQ 我依靠匿名委托来指定将使用哪些T类型的成员对集合进行分组和排序 public IEnumerable<T> GetList(IEnumerable<T> collection, Func<T, object> groupBy, Func<T, ob

我正在创建一个函数,它将获取一些IEnumerable,进行分组、排序,获取一些前N个元素,并返回这些元素的列表。它以后可能会做更多的工作,这就是为什么我想把它变成一个函数,而不仅仅是直接使用LINQ

我依靠匿名委托来指定将使用哪些T类型的成员对集合进行分组和排序

    public IEnumerable<T> GetList(IEnumerable<T> collection, Func<T, object> groupBy, Func<T, object> orderBy, int howMany)
    {
        var group = collection
            .GroupBy(groupBy)
            .Select(x => x.OrderBy(orderBy).Take(howMany))
            .Aggregate((l1, l2) => l1.Concat(l2));

        return group.ToList();
    }
public IEnumerable GetList(IEnumerable集合、Func groupBy、Func orderBy、int howMany)
{
变量组=集合
.GroupBy(GroupBy)
.Select(x=>x.OrderBy(OrderBy.Take(多少))
.骨料((l1,l2)=>l1.混凝土(l2));
returngroup.ToList();
}
然后像这样使用:

        new CollectionGroupPicker<NumericDomainObject>().GetList(list, x => x.GroupableField, x => x.OrderableField, 2).ToList();
newcollectiongrouppicker().GetList(list,x=>x.GroupableField,x=>x.OrderableField,2).ToList();

我的问题是-有没有更好的方法来传递我将使用哪个类型的成员进行分组和排序?我在这里使用的是object,但是有没有更好的方法?

而不是指定
object
您应该指定组并选择键作为通用参数。它们的类型将根据使用情况自动推断,调用方可以使用任何返回类型指定lambda

public IEnumerable<T> GetList<TGroupKey, TOrderKey>(IEnumerable<T> collection, 
                                                    Func<T, TGroupKey> groupBy, 
                                                    Func<T, TOrderKey> orderBy, 
                                                    int howMany)
{
    var group = collection
        .GroupBy(groupBy)
        .Select(x => x.OrderBy(orderBy).Take(howMany))
        .Aggregate((l1, l2) => l1.Concat(l2));
    return group.ToList();
}
public IEnumerable GetList(IEnumerable集合,
Func groupBy,
Func orderBy,
整数(多少)
{
变量组=集合
.GroupBy(GroupBy)
.Select(x=>x.OrderBy(OrderBy.Take(多少))
.骨料((l1,l2)=>l1.混凝土(l2));
returngroup.ToList();
}

您应该指定组并选择键作为通用参数,而不是指定
对象。它们的类型将根据使用情况自动推断,调用方可以使用任何返回类型指定lambda

public IEnumerable<T> GetList<TGroupKey, TOrderKey>(IEnumerable<T> collection, 
                                                    Func<T, TGroupKey> groupBy, 
                                                    Func<T, TOrderKey> orderBy, 
                                                    int howMany)
{
    var group = collection
        .GroupBy(groupBy)
        .Select(x => x.OrderBy(orderBy).Take(howMany))
        .Aggregate((l1, l2) => l1.Concat(l2));
    return group.ToList();
}
public IEnumerable GetList(IEnumerable集合,
Func groupBy,
Func orderBy,
整数(多少)
{
变量组=集合
.GroupBy(GroupBy)
.Select(x=>x.OrderBy(OrderBy.Take(多少))
.骨料((l1,l2)=>l1.混凝土(l2));
returngroup.ToList();
}

我同意Samuel使用通用的parmater类型。另外,为什么不使用
SelectMany
将结果展平,或者将其作为一种扩展方法

static class GetListExtensionMethods
{
    public static IEnumerable<T> GetList<T, TGroupingField, TOrderingField>(this IEnumerable<T> collection, Func<T, TGroupingField> groupBy, Func<T, TOrderingField> orderBy, int howMany)
    {
        var group = collection
            .GroupBy(groupBy)
            .SelectMany(x => x.OrderBy(orderBy).Take(howMany));
        return group.ToList();
    }
}
静态类GetListExtensionMethods
{
公共静态IEnumerable GetList(此IEnumerable集合、Func groupBy、Func orderBy、int howMany)
{
变量组=集合
.GroupBy(GroupBy)
.SelectMany(x=>x.OrderBy(OrderBy).Take(howmount));
returngroup.ToList();
}
}

我同意Samuel使用通用的parmater类型。另外,为什么不使用
SelectMany
将结果展平,或者将其作为一种扩展方法

static class GetListExtensionMethods
{
    public static IEnumerable<T> GetList<T, TGroupingField, TOrderingField>(this IEnumerable<T> collection, Func<T, TGroupingField> groupBy, Func<T, TOrderingField> orderBy, int howMany)
    {
        var group = collection
            .GroupBy(groupBy)
            .SelectMany(x => x.OrderBy(orderBy).Take(howMany));
        return group.ToList();
    }
}
静态类GetListExtensionMethods
{
公共静态IEnumerable GetList(此IEnumerable集合、Func groupBy、Func orderBy、int howMany)
{
变量组=集合
.GroupBy(GroupBy)
.SelectMany(x=>x.OrderBy(OrderBy).Take(howmount));
returngroup.ToList();
}
}

我很难找到“更好的方法”。您的解决方案看起来非常简洁。我建议的唯一更改是制作第二个版本,其方法签名为
IEnumerable GetList(IQueryable collection、Expression groupBy、Expression orderBy、int howMany)
,这样您就可以将其用于LinqToEntity(即:实体框架,LinqToSql,etc.。。(加上使用另一个通用参数(如答案所示)关闭
object
)@ScottChamberlain-谢谢。这是一个愚蠢的托利斯特()我草草加入测试。更改为返回组。如果您正在返回组,并且您按照我的建议使用IQueryable版本,请确保将返回类型也更改为
IQueryable
。我很难找到“更好的方法”您的解决方案看起来非常简洁。我建议的唯一更改是制作第二个版本,其方法签名为
IEnumerable GetList(IQueryable collection、Expression groupBy、Expression orderBy、int howMany)
,这样您就可以将其用于LinqToEntity(即:实体框架、LinqToSql等)。(再加上切换出
object
,使用另一个通用参数,如答案所示)@ScottChamberlain-谢谢你。这是一个愚蠢的ToList()我临时加入测试。更改为返回组。如果您正在返回组,并且您执行我建议的IQueryable版本,请确保将返回类型也更改为
IQueryable