【发布时间】:2014-09-26 23:48:31
【问题描述】:
我无法理解为什么 Program.Fetch1 和 Program.Fetch2 不会导致完全相同的执行顺序。唯一的区别是Program.Fetch1 调用Program.Fetch 来执行实际的获取操作。
class Program
{
static IEnumerable<int> Fetch1()
{
using (Context c = new Context())
{
return Fetch(c);
}
}
static IEnumerable<int> Fetch(Context c)
{
foreach (int i in c.Fetch())
{
yield return i;
}
}
static IEnumerable<int> Fetch2()
{
using (Context c = new Context())
{
foreach (int i in c.Fetch())
{
yield return i;
}
}
}
static void Main(string[] args)
{
Console.WriteLine("Fetch1:");
foreach (int i in Fetch1())
{
Console.WriteLine(i);
}
Console.WriteLine("Fetch2:");
foreach (int i in Fetch2())
{
Console.WriteLine(i);
}
}
}
class Context : IDisposable
{
public void Dispose()
{
Console.WriteLine("Context.Dispose");
}
public IEnumerable<int> Fetch()
{
return new int[] { 1, 2 };
}
}
输出:
Fetch1:
Context.Dispose
1
2
Fetch2:
1
2
Context.Dispose
我唯一的猜测是 Context.Dispose 在 Program.Fetch1 中首先被调用,因为 using 声明的范围已经离开。但Program.Fetch1 也是如此。那么为什么这些方法的行为不同呢?
更新:我的问题与yield return statement inside a using() { } block Disposes before executing重复
【问题讨论】:
-
您检查过为此代码生成的 IL 吗?
-
@Alex Voskresenskiy 不,我没有。但是我以前从未做过 IL 考试——所以我必须先弄清楚如何去做。
-
@Martin IL 的收益/回报太可怕了,我不会打扰。您可以尝试使用 ILSpy 进行反编译以查看 C# 中的状态机。
标签: c# .net idisposable using yield-return