【问题标题】:Reusing an IEnumerable<T> results in false result, e.g. on .Any()重用 IEnumerable<T> 会导致错误结果,例如任何()
【发布时间】:2011-06-22 17:45:36
【问题描述】:

我有点迷失在延期执行的土地上:

我声明了一个 IEnumerable 实现类的实例

var wordEnumerable = new WordEnumerable(_text);

然后我遍历它(第一个单词是“Lorem”)

foreach (var word in wordEnumerable)
                    Console.WriteLine(word);

.. 写入控制台。

现在我在代码中做一个

Console.WriteLine(wordEnumerable.Any(w => w == "Lorem"));

.. 并得到一个 False 作为输出。

现在,如果我将 .Any(..) 部分放在 foreach 循环上方,我确实得到了一个正确的结果,但是循环确实从第二个单词开始。

我的期望是 .Net 为每次调用 IEnumerable 及其底层 IEnumerator 创建不同的运行时“上下文”,因此它们不会干扰......我不想 .Reset( ) 手动操作以获得正确的结果?

我在这里错过了什么?

更新

.. 它基本上是一个 IEnumerable,它允许我遍历给定字符串中的单词。

【问题讨论】:

  • WordEnumerable如何实现IEnumerable&lt;T&gt;
  • 您能给我们提供更多关于 WordEnumerable 类的信息吗?使用简单的List&lt;string&gt; 创建您想要的功能我没有问题。如果两个代码片段之间的集合没有更改,那么如果 WordEnumerable 类按预期工作,您的代码应该也能正常工作。
  • 好了,添加了源链接

标签: .net ienumerable ienumerator deferred-execution


【解决方案1】:

您的期望是正确的 - Any 将再次调用 GetEnumerator 以获取新的 IEnumerator&lt;T&gt;。那应该没问题如果你正确地实现了IEnumerable&lt;T&gt;。我的猜测是您对WordEnumerable 的实现不正确。请发布代码:)

如果你写会发生什么:

Console.WriteLine("First");
foreach (var word in wordEnumerable)
{
    Console.WriteLine(word);
}

Console.WriteLine("Second");
foreach (var word in wordEnumerable)
{
    Console.WriteLine(word);
}

?要检查的另一件事是WordEnumerable 实现了IEnumerable&lt;string&gt; 而不是IEnumerable&lt;object&gt;,否则您的== 检查将是参考身份检查。

【讨论】:

  • 天哪.. 谢谢乔恩!我的错.. 我重用了 Enumerator :) 它是一个 IEnumerable,所以 == 比较确实可以正常工作。
猜你喜欢
  • 2021-10-11
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
  • 1970-01-01
  • 2016-01-06
相关资源
最近更新 更多