我可以在yield-return-method 中使用“using”吗?

2024-02-22

我刚刚看到了一个 YouTube 视频,其中导师使用了一个 Yield 返回方法来打开一个文件并从中读取行,这些行将 Yield 返回给调用者(实际代码位于 FileStream 周围的 using 块中)。

然后我想知道,在yield-return方法中使用“using”或“try-finally”是否可以。因为我的理解是,该方法仅运行与从中获取值一样长的时间。例如,使用“Any()”,该方法在第一次yield返回(或者当然是yieldbreak)之后完成。

那么,如果函数永远不会运行到结束,那么finally块什么时候执行呢?使用这样的构造安全吗?


IEnumerator<T>实施IDisposable, and foreach循环将在完成时处理它们正在枚举的东西(这包括使用foreach循环,例如.ToArray()).

事实证明,编译器生成的生成器方法的状态机实现了Dispose以一种聪明的方式:如果状态机处于“内部”状态using阻止,然后调用Dispose()在状态机上将处置受保护的事物using陈述。


让我们举个例子:

public IEnumerable<string> M() {
    yield return "1";
    using (var ms = new MemoryStream())
    {
        yield return "2";  
        yield return "3";
    }
    yield return "4";
}

我不会粘贴整个生成的状态机,因为它非常大。您可以在 SharpLab 上看到它 https://sharplab.io/#v2:EYLgZgpghgLgrgJwgZwLQBMD2MB2EYBimCAtrADTogDUAPgAIAMABPQIwAsA3ALABQTVmwB0ASQDyvAQGZWAJmYBhZgG9+zDa1ntpAHnaMAfMwCyACgCUq9Ztvs2rAOzMARGxdTbdlmYBuUBGYSZGYAXmY8AHdTCBJiAE8AZRgkKBJLCxsvaz5s7PsnVzkPDSy8jQL6ZxdpDzLbAF96zUrqjjrczSa+bqA==.

状态机的核心是以下 switch 语句,它跟踪我们通过每个状态的进度yield return声明:

switch (<>1__state)
{
    default:
        return false;
    case 0:
        <>1__state = -1;
        <>2__current = "1";
        <>1__state = 1;
        return true;
    case 1:
        <>1__state = -1;
        <ms>5__1 = new MemoryStream();
        <>1__state = -3;
        <>2__current = "2";
        <>1__state = 2;
        return true;
    case 2:
        <>1__state = -3;
        <>2__current = "3";
        <>1__state = 3;
        return true;
    case 3:
        <>1__state = -3;
        <>m__Finally1();
        <ms>5__1 = null;
        <>2__current = "4";
        <>1__state = 4;
        return true;
    case 4:
        <>1__state = -1;
        return false;
}

你可以看到我们创建了MemoryStream当我们进入状态 2 并处理它时(通过调用<>m__Finally1())当我们退出状态 3 时。

这是Dispose method:

void IDisposable.Dispose()
{
    int num = <>1__state;
    if (num == -3 || (uint)(num - 2) <= 1u)
    {
        try
        {
        }
        finally
        {
            <>m__Finally1();
        }
    }
}

如果我们处于状态 -3、2 或 3,那么我们将调用<>m__Finally1();。状态 2 和 3 是那些在using block.

(状态 -3 似乎是一个守卫,以防我们写yield return Foo() and Foo()抛出异常:在这种情况下,我们将停留在状态 -3 并且无法进一步迭代。然而,我们仍然可以处置MemoryStream在这种情况下)。

只是为了完整性,<>m__Finally1定义为:

private void <>m__Finally1()
{
    <>1__state = -1;
    if (<ms>5__1 != null)
    {
        ((IDisposable)<ms>5__1).Dispose();
    }
}

您可以在以下位置找到相关规范:C# 语言规范 https://www.microsoft.com/en-us/download/details.aspx?id=7029,第 10.14.4.3 节:

  • If the state of the enumerator object is suspended, invoking Dispose:
    • 将状态更改为正在运行。
    • 执行任何finally 块,就好像最后执行的yield return 语句是yield break 语句一样。如果这导致抛出异常并将其传播到迭代器主体之外,则枚举器对象的状态将设置为 after,并将异常传播到 Dispose 方法的调用方。
    • 将状态更改为之后。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我可以在yield-return-method 中使用“using”吗? 的相关文章

  • 如何管理返回到 QML 的动态分配的 QObject 的生命周期?

    我有这个代码 QVariant componentFromCode QString code QQmlComponent component new QQmlComponent engine engine gt setObjectOwner
  • Microsoft Visual C++ 2008 和 R2007b 的 Mex 类型

    我想对 vs2008 和 matlab2007b 使用 mex 类型 我尝试了下面的代码 include
  • 我可以在 WinRT / Windows 8 Store 应用程序中绑定 DynamicObject

    我有以下代码 public class MyClass DynamicObject INotifyPropertyChanged Dictionary
  • 当用户与 DateTimePicker 控件交互时会引发什么事件?

    我是 C 新手 在我的程序中使用 DateTimePicker Value Changed 事件 但我发现当用户单击箭头时发生 ValueChanged 事件 或者如果也以编程方式更改值 我只想识别 DateTimePicker 的用户交互
  • C# 中的 DateTime.Parse 抛出异常

    我不知道为什么抛出异常 这是工作代码 DateTime Parse 1 12 2012 12 00 00 AM 这是抛出异常的一个 DateTime Parse 1 13 2012 12 00 00 AM 抛出的异常是 格式异常 包括此消息
  • 从文本文件中读取所有内容 - C

    我正在尝试从文本文件中读取所有内容 这是我写的代码 include
  • 如何使构造函数只能由基类访问?

    如果我想要一个只能从子类访问的构造函数 我可以使用protected构造函数中的关键字 现在我想要相反的 我的子类应该有一个构造函数 该构造函数可以由其基类访问 但不能从任何其他类访问 这可能吗 这是我当前的代码 问题是子类有一个公共构造函
  • 相当于一个允许重复键的排序字典

    我需要一个数据结构 可以通过与对象关联的浮动键对对象进行排序 从低到低的在前 问题是键代表成本 所以经常有重复 我不关心这一点 因为如果两个具有相同的成本 我只会抓住第一个 因为它没有区别 问题是编译器抱怨 是否有一种数据结构的行为方式相同
  • 使用工作表作为数据源的 VSTO Excel 的简单示例

    我想我遇到了 最简单的答案是最难找到的答案 的情况 而且我还没有遇到过任何搜索能够以直接的方式给我这个答案 这是为了Excel 2010 and VS 2010在现有 VSTO C 项目中 我有一个 Excel 工作表 其中包含 4 列数据
  • Python NET 调用具有返回值和输出参数的 C# 方法

    我有以下静态 C 方法 public static bool TryParse string s out double result 我想使用 Python NET 包从 Python 调用它 import clr from System
  • 一个阻塞但非模态的 QDialog?

    我有一堆图像 我想对其执行一些操作 处理完每个图像后 我的程序应该弹出一个对话框 提示用户是否要继续处理下一个图像或中止 在此之前 他们应该有机会对图像或参数进行一些手动更改 无论如何 他们必须能够访问应用程序的窗口 而调用对话框的方法的执
  • 如何找到 QDockWidget 标题栏的高度?

    我正在尝试找到 a 的高度QDockWidget标题栏 以便对自定义布局进行一些智能调整大小 但标题栏不是单独的小部件 它内置于停靠小部件的私有布局中 并且没有成员可以访问它 还有其他方法可以找到它的高度吗 是的 您可以使用以下命令找到标题
  • 在javascript中调用c#函数[重复]

    这个问题在这里已经有答案了 可能的重复 从 Javascript 调用 ASP NET 函数 https stackoverflow com questions 3713 call asp net function from javascr
  • 在 QtCreator 中查看数组内容

    调试时是否可以在 Qt Creator 中查看数组的内容 似乎检测到我的数组是一个数组而不是一个指针 此外 我可以点击一个箭头 就像展开一样 但之后什么也没有显示 当我试穿的时候std vector Qt Creator 设法按预期显示内容
  • 如何将焦点设置到 Windows 窗体应用程序中的控件?

    在 Windows 窗体应用程序中 when我是否编写代码以在应用程序启动时以及随后调用函数后将焦点设置到控件 例如 如果我有一个 DropDownList 一个 TextBox 和四个按钮 并且我希望将 Focus 设置为 DropDow
  • 列表框显示类名称而不是值

    我正在开发一个项目 其中用户应该向动物输入值 名称 年龄 性别等 并且用户输入的值应该显示在列表框中 这些类相互继承 以下是继承的工作原理 Animalclass 是所有类的父类 Mammal类继承自Animal class Dog类继承自
  • 创建 .ICS 文件,添加到 Outlook

    我正在创建一个简单的应用程序 允许用户下载 ICS 文件 并将其导入到他们选择的日历应用程序 站点中 我对创建过程感到满意 但对在 Outlook 中打开它们有疑问 将使用C ASP NET进行开发 当我打开一个日历时 它会添加一个新日历
  • 为什么这些双精度数的返回值为-1.#IND?

    I have double score cvMatchContourTrees CT1 CT2 CV CONTOUR TREES MATCH I1 0 0 cout lt
  • 通过 boost::python 将 C++ 对象传递给 python 函数

    我想在 C 应用程序中使用嵌入 python 并调用 python 脚本中定义的函数 该函数的参数是一个 C 对象 看我的代码 class Test public void f std cout lt lt sss lt
  • 如果 foreach 是一个结构数组,它会复制每个元素吗?

    我有一个结构数组 做foreach运算符在迭代数组时复制每个元素 据我所理解foreach只是底层的语法糖转换为for 所以看来答案是否定的 但我很想得到一些确认 PS 看来应该有人已经问过了 但我无法轻易找到任何东西 因此 请以提供的参考

随机推荐

  • 如何管理grails中多个表的分页?

    我的 gsp 页面中有两个表 部分 我需要在它们上实现分页 表 节的每页中的记录数不同 例如 第一个表应每页显示 10 条记录 第二个表 节应每页显示 7 条记录 我使用标签来实现它 当我这样做时 我遇到了很多问题 如下所述 最初 它显示每
  • 设置应用程序图标 (Xcode 7)

    我环顾四周 我发现的其他主题都没有解决我在应用程序图标中遇到的错误 当我尝试运行我的应用程序时 出现错误 名为 AppIcon 的应用程序图标集没有任何适用的内容 我很确定这是因为我没有将 png 文件放在正确的位置 但我不知道将其放在哪里
  • 在 Rails 4 中发送带有远程 true 的表单

    我有一个用于更新图像的表格 该行动有 respond to do format format js format html end 但我收到以下错误 ActionView MissingTemplate Missing template u
  • 使用 For 循环在 Oracle 过程中检索多行

    我正在处理存储过程 我需要检索一组结果并单独处理每个元素 然后返回整个结果 使用 3 个不同的表 我对数据库不太熟悉 但这就是我能想到的 create or replace procedure GET EMP RSLT IS CURSOR
  • 当您收到通用 SoapException:服务器无法处理请求时,如何缩小实际问题的范围。来自MS-CRM 4.0

    我最近开始针对 CRM 4 0 进行编程 并使用 CrmService 发出这些请求 当我发送请求时 我经常在使用的动态实体的某些属性中得到错误的值 当然请求失败了 我拦截异常并记录它 问题是这就是我得到的 System Web Servi
  • Lua 匹配字符串中字符后的所有内容

    我是 Lua 新手 不太了解模式匹配 我试图弄清楚如何匹配冒号后字符串中的所有内容 并将字符串的该部分放入变量中 我在网上浏览的运气不太好 或者也许我只是没有看到它 那么我该怎么做呢 例如 假设我有一个名为my string等于 hello
  • Discord.py 获取自定义状态

    如何通过discord py获取Discord用户自定义状态 我看过discord py 文档 我唯一能找到的是Member status https discordpy readthedocs io en latest api html
  • 为什么除法结果会根据强制转换类型而有所不同? (跟进)

    这是这个问题的后续 为什么除法结果会根据强制转换类型而有所不同 https stackoverflow com questions 25703304 why does a division result differ based on th
  • C++11 向量构造函数复制与范围?

    我无法理解向量复制构造函数和范围构造函数之间的优点或区别 当我像这样构造三个向量时 vector
  • 如何禁用 React Native 中的警告?

    我知道警告很重要 但出于特定原因 我不希望它们出现在屏幕上 如何禁用出现的黄色警告screen console disableYellowBox已被弃用 取而代之的是LogBox ignoreAllLogs 在index js中只需设置 i
  • 如何在 Pandas 中创建 SparseDataFrame?

    pandas DataFrame a Out 41 1 2 3 0 1 2 NaN 1 1 NaN 3 a 1 1 0 2 2 0 1 1 0 3 3 0 pandas DataFrame a Out 43 1 2 3 0 1 2 NaN
  • Qt 中的 GIF 动画

    我用过QGraphicsView QGraphicsScene类以便在小部件中显示图片 如下所示 m Scene gt addPixmap QPixmap fileName m View gt setScene m Scene 我如何展示
  • CSS calc 在 IE11 中无法使用线性渐变

    margin 0 padding 0 body background color orangered content margin top 200px height 100vh background color fdfdff tilt po
  • 多个HTTP请求触发HTTP Client超时

    我有一个异步发送 500 个 HTTP 请求的应用程序 所有请求均已处理after由于 HTTP 客户端超时 15 秒失败 even当请求的端点已返回 200 OK 时 代码非常简单 这里我们获取一大块请求 500 并异步执行它们 应该注意
  • 64位nasm除法idiv [重复]

    这个问题在这里已经有答案了 print out division message mov rcx 0 zero out register mov rax input mov rcx input2 idiv rcx divide rax by
  • 在 python 中具有任意数量的带有命名默认值的参数

    我想用 python 编写一个函数 除了一个命名参数 带有默认值 之外 它还可以接受任意数量的未命名参数 例如 我想写这样的东西 def myFunc args optDefault 1 但这只是给出了语法错误 有没有等效的方法来做到这一点
  • 如何在 Bash 中操作十六进制值?

    我有一个具有十六进制值的变量 在本例中 一个值为 0xfe 的字节 echo MYVAR hexdump 0000000 0afe 0000002 我想在我的 bash 脚本中使用这个值 特别是我需要 用作字符串 echo X MYVAR
  • spring中rabbitmq监听器的异常处理

    使用spring 我是rabbitmq的新手 我想知道我错在哪里 我编写了一个rabbitmq连接工厂和一个包含侦听器的侦听器容器 我还为侦听器容器提供了错误处理程序 但它似乎不起作用 我的春豆
  • Python google app engine 的最佳部署策略

    我想知道是否有在 Google 应用程序引擎 特别是 Django 上部署 python 应用程序的最佳实践 模式 最佳实践应该是现有最佳实践的组合 即 Fabric Paver Buildout 等 另请分享开发的最佳实践模式 我无法让
  • 我可以在yield-return-method 中使用“using”吗?

    我刚刚看到了一个 YouTube 视频 其中导师使用了一个 Yield 返回方法来打开一个文件并从中读取行 这些行将 Yield 返回给调用者 实际代码位于 FileStream 周围的 using 块中 然后我想知道 在yield ret