2016-04-29 42 views
0

我有两种方法在结构上非常相似:如何使用泛型来创建通用的分块算法?

public static List<List<NodeAttribute>> chunkList(List<NodeAttribute> list, int nSize = 30) 
    { 
     List<List<NodeAttribute>> chunkedList = new List<List<NodeAttribute>>(); 

     for (var i = 0; i < list.Count; i += nSize) 
     { 
      chunkedList.Add(list.GetRange(i, Math.Min(nSize, list.Count - i))); 
     } 

     return chunkedList; 
    } 

public static List<List<int>> chunkList(List<int> list, int nSize = 30) 
    { 
     List<List<int>> chunkedList = new List<List<int>>(); 

     for (var i = 0; i < list.Count; i += nSize) 
     { 
      chunkedList.Add(list.GetRange(i, Math.Min(nSize, list.Count - i))); 
     } 

     return chunkedList; 
    } 

理想情况下,我想有一个可以采取任何类型和返回列表的通用方法该类型的列表的列表 - 而不是只为我可能需要的每种对象类型添加方法。我知道我可以使用泛型来做到这一点,但是如何使返回类型与输入一样具有泛型?

回答

8

对方回答确实说明了如何使用参数多态性的一个好工作 - 你有两种方法在结构上相同,仅在一个类型不同,所以你可以泛化它通过制作一个由该类型参数化的方法。

但是我们也可以借此机会退后一步,问我们是否可以解决一个更普遍的问题。假设您有一个序列 - 比列表更通用 - 并且您希望将其分组为序列序列。没有必要限制自己的名单,你可以在任何类型的序列做此操作:

public static IEnumerable<IEnumerable<T>> Chunk(
    this IEnumerable<T> items, int size) 
{ 
    return items 
    .Select((item, index) => new { Group = index/size, Item = item }) 
    .GroupBy(x => x.Group) 
    .Select(group => group.Select(g => g.Item)); 
} 

如果你希望它是名单毕竟名单,这是很容易的;将最后一行更改为:

.Select(group => group.Select(g => g.Item).ToList()).ToList(); 
5

将方法定义为泛型,然后您可以使用相同的泛型类型声明参数并返回。

事情是这样的:

public static List<List<T>> ChunkList<T>(List<T> list, int nSize = 30) 
{ 
    List<List<T>> chunkedList = new List<List<T>>(); 

    for (var i = 0; i < list.Count; i += nSize) 
    { 
     chunkedList.Add(list.GetRange(i, Math.Min(nSize, list.Count - i))); 
    } 

    return chunkedList; 
} 
相关问题