繁体   English   中英

编写自己的扩展程序时应该使用Yield吗?

[英]Should I use Yield when writing my own extension?

我想编写一个扩展方法(用于流利的语法),以便如果序列是:

List< int> lst  = new List< int>(){1,2,3 };

我想重复3次(例如)。 所以输出将是123123123

我写了这个:

 public static  IEnumerable<TSource>  MyRepeat<TSource>(this IEnumerable<TSource>  source,int n)
    {
         return    Enumerable.Repeat(source,n).SelectMany(f=>f);
    }

现在我可以这样做:

  lst.MyRepeat(3)

输出:

在此处输入图片说明

题 :

我不应该在扩展方法中使用Yield吗? 我尝试了yield return但在这里不起作用。 这是为什么,我应该使用它。

编辑

在Ant回答之后,我将其更改为:

public static  IEnumerable<TSource>  MyRepeat<TSource>(this IEnumerable<TSource>  source,int n)
    {
        var k=Enumerable.Repeat(source,n).SelectMany(f=>f);

                foreach (var element in k)
                {
                    yield   return    element;
                }
    }

但是有什么区别吗?

这是因为以下内容已返回 IEnumerable:

Enumerable.Repeat(source,n).SelectMany(f=>f);

当使用yield关键字时,您可以指定对该方法的给定迭代将返回以下内容。 因此,您实际上是在说“每次迭代都会产生一个IEnumerable<TSource> ”,实际上,返回IEnumerable<TSource>的方法上的每次迭代都应该产生一个TSource

因此,您的错误-当您遍历MyRepeat ,应该返回一个TSource但是由于您尝试yield IEnumerable ,因此实际上是在尝试从每次迭代中返回IEnumerable而不是返回单个元素。

您的编辑应该可以进行,但毫无意义-如果您直接直接返回IEnumerable,则直到您对其进行迭代(或调用ToList )之前,它都不会被枚举。 在第一个示例中, SelectMany (或其嵌套方法之一)已经在使用yield ,这意味着yield已经存在,它只是隐式存在于您的方法中。

蚂蚁P的答案当然是正确的。

如果您要构建自己返回的可枚举数,则可以使用yield,而不要依赖SelectMany。 例如:

public static IEnumerable<T> Repeat<T>(this IEnumberable<T> items, int repeat)
{
    for (int i = 0; i < repeat; ++i)
        foreach(T item in items)
            yield return item;
}

您产生的东西是序列的元素 该代码是用于产生屈服元素序列的指令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM