【问题标题】:Method signature for IList<T>.Split() extension methodIList<T>.Split() 扩展方法的方法签名
【发布时间】:2010-12-23 06:38:06
【问题描述】:

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

// 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);

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

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

但是当我尝试编译它时,编译器告诉我IList&lt;&gt;ICollection&lt;&gt;IEnumerable&lt;&gt; 需要一个类型参数。因此,我将定义更改为:

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

然后编译器抱怨它找不到类型TList。我有一个想法,我把事情复杂化了,但我看不出……任何帮助都值得赞赏!

【问题讨论】:

    标签: c# generics .net-3.5 extension-methods


    【解决方案1】:

    是的,我认为你把事情复杂化了。试试这个:

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

    毕竟,您不会根据源代码更改在方法中创建的列表类型,是吗?即使我通过了其他一些实现,您也可能会创建一个List&lt;T&gt;(或者可能是一个T[])。

    您可能希望查看Batch method in MoreLINQ 以了解基于IEnumerable&lt;T&gt; 的实现。

    【讨论】:

    • 谢谢乔恩,打字时间太长了!哈。
    【解决方案2】:

    这个怎么样:

    public static IList<TResult>[] Split<TSource, TResult>(
        this IList<TSource> source,      // input IList to split
        Func<TSource, TResult> selector, // projection to apply to each item
        int elementCount                 // number of items per IList
    ) {
        // do something        
    }
    

    如果您不需要版本来投影每个项目:

     public static IList<T>[] Split<T>(
        this IList<T> source, // input IList to split
        int elementCount      // number of items per IList
    ) {
          return Split<T, T>(source, x => x, elementCount);      
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-01
      • 2015-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-08
      • 2017-01-31
      • 2014-06-07
      相关资源
      最近更新 更多