.NET IEnumerator<string> 在屈服 block 中时不会在 MoveNext 上前进

标签 .net yield-return

下面的代码(用于在 LinqPad 中运行)旨在将“foo/skip/bar”字符串解析为项目对象,跳过“skip”位,生成“foo”和“bar”的项目对象。运行时,会生成 2 个“条形”项目。

在 TryGetChild 方法中,当找到“skip”时,枚举数将从“skip”向前移动到“bar”。但是,当执行返回到调用方法时,枚举器又回到“跳过”状态。

我认为这是一些yield block 的奇怪之处,就好像我在Main()中进行分割并将枚举器传递到Walk()中一样,它可以正常工作。有人能解释一下枚举器是如何返回的吗?是否正在创建新的?

编辑:这是我在代码中发现的看似奇怪的情况的非常简化的版本。我问这个问题是出于好奇,而不是寻找我已经找到的解决方法。

/* output from program

enumerator moved to foo
enumerator moved to skip
enumerator moved to bar
enumerator moved to bar

Item [] (3 items)  

foo
bar     
bar
*/     


static void Main()
{
    Walk("foo/skip/bar").ToArray().Dump();
}

private static IEnumerable<Item> Walk(string pathString)
{
    var enumerator = pathString.Split('/').ToList().GetEnumerator();
    var current = new Item() { S = "" };
    while (enumerator.MoveNext())
    {
        Console.WriteLine("enumerator moved to " + enumerator.Current);
        yield return current.TryGetChild(enumerator);
    }
}
class Item
{
    public string S { get; set; }

    public Item TryGetChild(IEnumerator<string> enumerator)
    {
        if (enumerator.Current == "skip")
        {
            enumerator.MoveNext(); //iterator moves on to 123
            Console.WriteLine("enumerator moved to " + enumerator.Current);
        }
        return new Item() { S = enumerator.Current };
    }
}

最佳答案

您看到此行为的原因是 List<T>.GetEnumerator()返回 List<T>.Enumerator 的实例,这是一个结构。因此,您将值类型传递给 TryGetChild()方法,并且该类型的任何突变(包括 MoveNext() 所做的突变)将不会反射(reflect)在调用者中。

关于.NET IEnumerator<string> 在屈服 block 中时不会在 MoveNext 上前进,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7207548/

相关文章:

.net - 在 Windows Powershell(或 dotNet 又名 .net)中执行 textwrap 和 dedent

node.js - Nodejs Express knex主详细记录更新

c# - yield 返回用法

c# - 如何使 `await …` 与 `yield return` 一起工作(即在迭代器方法中)?

c# - C#中 "yield"关键字有什么用?

c# - 如何让 VS 2010 默认创建 x64 项目?

c# - 如何根据加利福尼亚州的当前时间将 UTC 转换为 PST 或 PDT?

c# - .NET 中的多线程 - 在后台实现计数器

c# - ASP.Net Web API - 同步获取 POSTed 文件?

c# - 复制 IEnumerable,替换一个项目