如何使[示例]扩展方法更加通用/实用/高效?

发布于 2024-09-18 02:05:48 字数 1070 浏览 8 评论 0 原文

我需要一个 double[] 通过跨步 y 分成 x 元素组,返回一个列表。非常基本...一个循环和/或一些 linq 以及所有设置。然而,我并没有在扩展方法上花费太多时间,这看起来是一些练习的不错选择。 朴素版本返回我在当前应用程序中寻找的内容...

(A)
public static IList<T[]> Split<T>(this IEnumerable<T> source, int every, int take)
{
  /*... throw E if X is insane ...*/
  var result = source
               .Where ((t, i) => i % every == 0)
               .Select((t, i) => source.Skip(i * every).Take(take).ToArray())
               .ToList();
  return result;
}

...返回类型是通用的...取决于您对通用的定义

我认为...

(B)    
public static IEnumerable<IEnumerable<T>> Split<T>
                  (this IEnumerable<T> source,int every, int take){/*...*/}

...是一个更好的解决方案...也许。

问题:

  • (B)是首选吗?...为什么?
  • 您如何将 (B) 转换为 IList
  • 重构有什么好处吗? 可能 两种可能被链接起来的方法或类似的方法。
  • 这种方法合理吗?...或者我有吗? 错过了一些基本的东西。

评论、意见和严厉的语言总是受到赞赏。

使用环境:C# .Net 4.0

I needed a double[] split into groups of x elements by stride y returning a List. Pretty basic...a loop and/or some linq and your all set. However, I have not been spending much time on extension methods and this looked like a good candidate for some practice. The naive version returns what I am looking for in my current application....

(A)
public static IList<T[]> Split<T>(this IEnumerable<T> source, int every, int take)
{
  /*... throw E if X is insane ...*/
  var result = source
               .Where ((t, i) => i % every == 0)
               .Select((t, i) => source.Skip(i * every).Take(take).ToArray())
               .ToList();
  return result;
}

...the return type is sort of generic...depending on your definition of generic.

I would think...

(B)    
public static IEnumerable<IEnumerable<T>> Split<T>
                  (this IEnumerable<T> source,int every, int take){/*...*/}

...is a better solution...maybe.

Question(s):

  • Is (B) preferred ?...Why ?
  • How would you cast (B) as IList <T[]> ?
  • Any benefit in refactoring ? possibly
    two methods that might be chained or the like.
  • Is the approach sound ?...or have I
    missed something basic.

Comments, opinions and harsh language are always appreciated.

Usage Context: C# .Net 4.0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤城病女 2024-09-25 02:05:48

B 可能是更好的选择。实际上,主要的变化是代码的使用者可以选择在方法末尾使用 ToList() 将其设置为列表,而不是被迫处理列表(实际上是 IList,无法迭代) 。

这在方法链接和一般使用方面有很多优点。 ToList() 是可枚举的很容易,但很难采用其他方法。因此,您可以在列表上调用 Select().Split().OrderBy() 并在 foreach 语句中使用结果,而不必让 Linq 立即迭代整个过程。

重构为yield return单个值可能会给你带来性能奖励,但由于你基本上只是返回 Select 给你的迭代器(它一次会产生一个项目),我不这样做认为你自己通过它屈服会得到很多好处。

B is probably the better option. Really the major change is that the consumer of the code has the option to make it a list using ToList() on the end of your method, instead of being forced to deal with a List (an IList, actually, which cannot be iterated).

This has a LOT of advantages in method chaining and general use. It's easy to ToList() an enumerable, but hard to go the other way. So, you can call Select().Split().OrderBy() on a list and use the results in a foreach statement without having to have Linq iterate through the whole thing at once.

Refactoring to yield return single values MIGHT get you a performance bonus, but since you're basically just returning the iterator that the Select gave you (which will yield one item at a time itself) I don't think you'll get much benefit in yielding through it yourself.

在风中等你 2024-09-25 02:05:48

我更喜欢 (B),因为它看起来更灵活。将 (B) 方法的输出转换为 IList 的一种方法与链接 .Select(x => x.ToArray()) 一样简单。 ToList() 到它,例如,

var foo = 
    bar.Split(someEvery, someTake).Select(x => x.ToArray()).ToList();

I would prefer (B) as it looks more flexible. One way of casting the output of the (B) method to an IList<T[]> is as simple as chaining .Select(x => x.ToArray()).ToList() to it, e.g.,

var foo = 
    bar.Split(someEvery, someTake).Select(x => x.ToArray()).ToList();
最初的梦 2024-09-25 02:05:48

在 .Net 4 中,您只需将返回类型更改为 IEnumerable> 即可。

在 .Net 4 之前,您必须首先通过在 上调用 .Cast>() 将内部列表转换为 IEnumerable返回之前的结果

In .Net 4, you can just change the return type to IEnumerable<IEnumerable<T>> and it will work.

Before .Net 4, you would have to cast the internal lists to IEnumerable first, by just calling .Cast<IEnumerable<T>>() on your result before returning.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文