c# - 使用嵌套方法时奇怪的执行顺序,yield return 和组合使用

标签 c# .net idisposable using yield-return

<分区>

我无法理解为什么 Program.Fetch1Program.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.DisposeProgram.Fetch1 中首先被调用,因为 using 声明的范围已经离开。但对于 Program.Fetch1 也是如此。那么为什么这些方法的行为不同呢?

更新:我的问题与 yield return statement inside a using() { } block Disposes before executing 重复

最佳答案

那是因为这些选项实际上是不同的:

  • FetchFetch2,使用 yield,创建一个状态机以能够返回未实现的 IEnumerable .
  • Fetch1 中,您只需调用 Fetch 并返回生成的状态机并处理上下文,而无需等待 IEnumerable 实际成为实现。

基本上,不同之处在于,在 Fetch2 中,您有一层延迟执行(使用 yield),而在 Fetch1 中,您没有,这意味着当您返回时,使用范围会立即结束。

关于c# - 使用嵌套方法时奇怪的执行顺序,yield return 和组合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25119785/

相关文章:

c# - 使用 PInvoke 时,何时应使用 class,何时应在要求输入指向 NAME 结构的指针时使用 struct?

c# - AddWithValue sql 注入(inject)安全吗?为什么?

c# - c#中是否有类似SQL IN语句的比较运算符

c# - 使用 XmlSerializer 时如何添加换行符

c# - Winforms 在文本框上禁用键盘输入但保持文本框启用

c# - 判断是否因为抛出异常而执行到 finally block 中

c# - 为什么不能使用 c# 对象初始值设定项语法调用方法?

c# - QueryObject 包含 Entity Framework

c# - 终结器中处置的资源与处置中释放的资源有什么区别

powershell - 我/我需要如何处置自定义PSObject?