如果我单步执行以下代码,则会跳过对ReturnOne()的调用。
static IEnumerable<int> OneThroughFive()
{
ReturnOne();
yield return 2;
yield return 3;
yield return 4;
yield return 5;
}
static IEnumerator<int> ReturnOne()
{
yield return 1;
}
我只能假设编译器正在剥离它,因为我正在做的是无效的。我希望能够将我的枚举分离成各种方法。这可能吗?
答案 0 :(得分:30)
您实际上并未使用ReturnOne
的结果。您正在调用该方法,并忽略返回值...这意味着您实际上从未看到任何代码正在运行。你可以这样做:
static IEnumerable<int> OneThroughFive()
{
foreach (int x in ReturnOne())
{
yield x;
}
yield return 2;
yield return 3;
yield return 4;
yield return 5;
}
C#没有(目前至少:)有一种“全部收益”结构。
你没有进入它的事实与你在迭代器块中有一个调用的事实无关 - 只是在你开始使用结果之前迭代器块的代码,没有代码运行。这就是为什么你需要将参数验证与屈服分开。例如,请考虑以下代码:
public IEnumerator<string> ReturnSubstrings(string x)
{
if (x == null)
{
throw ArgumentNullException();
}
for (int i = 0; i < x.Length; i++)
{
yield return x.Substring(i);
}
}
...
ReturnSubstring(null); // No exception thrown
你需要这样写:
public IEnumerator<string> ReturnSubstrings(string x)
{
if (x == null)
{
throw ArgumentNullException();
}
return ReturnSubstringsImpl(x);
}
private IEnumerator<string> ReturnSubstringsImpl(string x)
{
for (int i = 0; i < x.Length; i++)
{
yield return x.Substring(i);
}
}
有关详细信息,请阅读深度C#的第6章 - 这恰好是第一版中的免费章节:) Grab it here。