在下面的测试中,我无法在使用yield return时真正打印Console.WriteLine。
我正在尝试收益率回报,我理解我对它的理解缺少了一些东西,但却无法弄清楚它是什么。为什么不在PrintAllYield
内打印字符串?
代码:
class Misc1 {
public IEnumerable<string> PrintAllYield(IEnumerable<string> list) {
foreach(string s in list) {
Console.WriteLine(s); // doesn't print
yield return s;
}
}
public void PrintAll(IEnumerable<string> list) {
foreach(string s in list) {
Console.WriteLine(s); // surely prints OK
}
}
}
测试:
[TestFixture]
class MiscTests {
[Test]
public void YieldTest() {
string[] list = new[] { "foo", "bar" };
Misc1 test = new Misc1();
Console.WriteLine("Start PrintAllYield");
test.PrintAllYield(list);
Console.WriteLine("End PrintAllYield");
Console.WriteLine();
Console.WriteLine("Start PrintAll");
test.PrintAll(list);
Console.WriteLine("End PrintAll");
}
}
输出:
Start PrintAllYield
End PrintAllYield
Start PrintAll
foo
bar
End PrintAll
1 passed, 0 failed, 0 skipped, took 0,39 seconds (NUnit 2.5.5).
答案 0 :(得分:11)
您必须实际枚举返回的IEnumerable
以查看输出:
Console.WriteLine("Start PrintAllYield");
foreach (var blah in test.PrintAllYield(list))
; // Do nothing
Console.WriteLine("End PrintAllYield");
当您使用yield return
关键字时,编译器将为您构建状态机。它的代码只有在您实际使用它来迭代返回的可枚举时才会运行。
您是否有特殊原因尝试使用yield return
打印出一系列string
s?这并不是该功能的目的,即简化序列生成器的创建,而不是已经生成的序列的枚举。 foreach
是后者的首选方法。