IList <T> .Split()扩展方法的方法签名

Ian*_*emp 2 c# generics extension-methods .net-3.5

我希望能够编写以下代码:

// contains 500 entries
IList<string> longListOfStrings = ...

// shorterListsOfStrings is now an array of 5 IList<string>,
// with each element containing 100 strings
IList<string>[] shorterListsOfStrings = longListOfStrings.Split(5);
Run Code Online (Sandbox Code Playgroud)

为此,我必须创建一个名为的泛型扩展方法Split,如下所示:

public static TList[] Split<TList>(this TList source, int elementCount)
  where TList : IList<>, ICollection<>, IEnumerable<>, IList, ICollection, IEnumerable
{
  return null;
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试编译时,编译器告诉我IList<>,ICollection<>并且IEnumerable<>需要一个类型参数.所以,我将定义更改为以下内容:

public static TList<TType>[] Split<TList<TType>>(this TList<TType> source, int elementCount)
  where TList : IList<TType>, ICollection<TType>, IEnumerable<TType>, IList, ICollection, IEnumerable
{
  return null;
}
Run Code Online (Sandbox Code Playgroud)

但随后编译器抱怨它无法找到类型TList.我有一个想法,我过于复杂的事情,但我看不出如何...任何帮助表示赞赏!

Jon*_*eet 6

是的,我认为你过于复杂.试试这个:

public static IList<T>[] Split<T>(this IList<T> source, int elementCount)
{
    // What the heck, it's easy to implement...
    IList<T>[] ret = new IList<T>[(source.Count + elementCount - 1) 
                                  / elementCount];
    for (int i = 0; i < ret.Length; i++)
    {
        int start = i * elementCount;
        int size = Math.Min(elementCount, source.Count - i * start);
        T[] tmp = new T[size];
        // Would like CopyTo with a count, but never mind
        for (int j = 0; i < size; j++)
        {
            tmp[j] = source[j + start];
        }
        ret[i] = tmp;
    }
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

毕竟,你不会根据来源改变你在方法中创建的那种列表,不是吗?即使我传入其他一些实现,你也可能创建一个List<T>(或者可能是一个T[]).

您可能希望在MoreLINQ中查看IEnumerable<T>基于基于实现的Batch方法.