How to yield return inside anonymous methods?

后端 未结 7 483
南笙
南笙 2021-01-07 16:43

Basically I have an anonymous method that I use for my BackgroundWorker:

worker.DoWork += ( sender, e ) =>
{
    foreach ( var effect in Glob         


        
7条回答
  •  野趣味
    野趣味 (楼主)
    2021-01-07 17:05

    For new readers: the most elegant way to implement 'anonymous iterators' (i. e. nested in other methods) in C#5 is probably something like this cool trick with async/await (don't be confused by these keywords, the code below is computed absolutely synchronously - see details in the linked page):

            public IEnumerable Numbers()
            {
                return EnumeratorMonad.Build(async Yield =>
                {
                    await Yield(11);
                    await Yield(22);
                    await Yield(33);
                });
            }
    
            [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethod]
            public void TestEnum()
            {
                var v = Numbers();
                var e = v.GetEnumerator();
    
                int[] expected = { 11, 22, 33 };
    
                Numbers().Should().ContainInOrder(expected);
    
            }
    

    C#7 (available now in Visual Studio 15 Preview) supports local functions, which allow yield return:

    public IEnumerable Filter(IEnumerable source, Func filter)
    {
        if (source == null) throw new ArgumentNullException(nameof(source));
        if (filter == null) throw new ArgumentNullException(nameof(filter));
    
        return Iterator();
    
        IEnumerable Iterator()
        {
            foreach (var element in source) 
            {
                if (filter(element)) { yield return element; }
            }
        }
    }
    

提交回复
热议问题