首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >泛型扩展方法可以返回类型的IEnumerable吗?

泛型扩展方法可以返回类型的IEnumerable吗?
EN

Stack Overflow用户
提问于 2015-08-21 11:45:16
回答 3查看 434关注 0票数 2

我想写一个具有泛型参数的扩展。让我用密码展示一下。

代码语言:javascript
复制
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> value, int countOfEachPart) 
{
    //spliting value
}

此方法总是返回IEnumerable<IEnumerable<T>>

但我想要回一些像IEnumerable<TList<T>>这样的想法

例如;

如果我通过了List<T>,我应该返回IEnumerable<List<T>>

如果我通过了T[],我应该返回IEnumerable<T>[]

等。

我试过这段代码,但没能成功

代码语言:javascript
复制
public static IEnumerable<TList<T>> Split<TList,T>(this TList<T> value, int countOfEachPart) where TList:IEnumerable<T> //or where TList:IEnumerable
{
    //spliting value
}

是否有任何方法返回传递的IEnumerable类型?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-08-21 11:56:59

因为您很可能必须实现对数组和列表的支持,所以您必须编写重载的方法。

代码语言:javascript
复制
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> value, int countOfEachPart)     

public static IEnumerable<IList<T>> Split<T>(this IList<T> value, int countOfEachPart) 

public static IEnumerable<T[]> Split<T>(this T[] value, int countOfEachPart) 

关于方法的逻辑(实际上不是问题的一部分,而是在您自己的回答中已经讨论过):我实现了一个类似的方法,只基于IEnumerables。看起来是这样的:

代码语言:javascript
复制
    public static IEnumerable<IEnumerable<T>> Page<T>(this IEnumerable<T> source, int pageSize)
    {
        T[] sourceArray = source.ToArray();
        int pageCounter = 0;
        while (true)
        {
            if (sourceArray.Length <= pageCounter * pageSize)
            {
                break;
            }
            yield return sourceArray
                .Skip(pageCounter * pageSize)
                .Take(pageSize);

            pageCounter++;
        }
    }

我对此并不完全满意,因为ToArray。我更希望找到这样一种解决方案:整个问题尽可能懒惰,并且只在迭代结果时迭代源。这会更复杂一些,我没有时间。但是,它可以很容易地被以后更好的实现所取代。

票数 4
EN

Stack Overflow用户

发布于 2015-08-21 14:03:08

我完成了分机。

我用了“Stefan Steinegger”和“Luaan的答案”。谢谢

这是我扩展的最后代码。我对你的批评和建议持开放态度

代码语言:javascript
复制
public static class Extension
    {
        private static IEnumerable<TList> Split<TList, T>(this TList value, int countOfEachPart) where TList : IEnumerable<T>
        {
            int cnt = value.Count() / countOfEachPart;
            List<IEnumerable<T>> result = new List<IEnumerable<T>>();
            for (int i = 0; i <= cnt; i++)
            {
                IEnumerable<T> newPart = value.Skip(i * countOfEachPart).Take(countOfEachPart).ToArray();
                if (newPart.Any())
                    result.Add(newPart);
                else
                    break;
            }

            return result.Cast<TList>();
        }

        public static IEnumerable<IDictionary<TKey, TValue>> Split<TKey, TValue>(this IDictionary<TKey, TValue> value, int countOfEachPart)
        {
            IEnumerable<Dictionary<TKey, TValue>> result = value.ToArray()
                                                                .Split(countOfEachPart)
                                                                .Select(p => p.ToDictionary(k => k.Key, v => v.Value));
            return result;
        }

        public static IEnumerable<IList<T>> Split<T>(this IList<T> value, int countOfEachPart)
        {
            return value.Split<IList<T>, T>(countOfEachPart);
        }

        public static IEnumerable<T[]> Split<T>(this T[] value, int countOfEachPart)
        {
            return value.Split<T[], T>(countOfEachPart);
        }

        public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> value, int countOfEachPart)
        {
            return value.Split<IEnumerable<T>, T>(countOfEachPart);
        }
    }
票数 1
EN

Stack Overflow用户

发布于 2015-08-21 11:49:40

TList是一个类型参数-它不是泛型的。但这不一定是:

代码语言:javascript
复制
public static IEnumerable<TList> Split<TList,T>
  (this TList value, int countOfEachPart) 
  where TList: IEnumerable<T>

遗憾的是,这不允许T的类型推断.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32139492

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档