收益率返回与返回 IEnumerable

2023-12-30

我注意到阅读时有一些好奇的事情IDataReader在我无法理解的 using 语句中。虽然我确信答案很简单。

为什么在里面时using (SqlDataReader rd) { ... }如果我直接执行yield return阅读器在阅读期间保持打开状态。但如果我直接执行return调用 SqlDataReader 扩展方法(如下所述),读取器在可枚举可实现之前关闭?

public static IEnumerable<T> Enumerate<T>(this SqlDataReader rd)
{
    while (rd.Read())
        yield return rd.ConvertTo<T>(); //extension method wrapping FastMember

    rd.NextResult();
}

为了完全清楚我的要求,我不确定为什么以下内容有根本不同:

根据 @TimSchmelter 的要求,一个充实的示例:

/*
 * contrived methods
 */
public IEnumerable<T> ReadSomeProc<T>() {
    using (var db = new SqlConnection("connection string"))
    {
        var cmd = new SqlCommand("dbo.someProc", db);

        using(var rd = cmd.ExecuteReader())
        {
            while(rd.Read())
                yield return rd.ConvertTo<T>(); //extension method wrapping FastMember
        }
    }
}


//vs
public IEnumerable<T> ReadSomeProcExt<T>() {
    using (var db = new SqlConnection("connection string"))
    {
        var cmd = new SqlCommand("dbo.someProc", db);

        using(var rd = cmd.ExecuteReader())
        {
            return rd.Enumerate<T>(); //outlined above
        }
    }
}

/*
 * usage
 */
var lst = ReadSomeProc<SomeObect>();

foreach(var l in lst){
    //this works
}

//vs
var lst2 = ReadSomeProcExt<SomeObect>();

foreach(var l in list){
    //throws exception, invalid attempt to read when reader is closed
}

Summary:该方法的两个版本defer, 但是因为ReadSomeProcExt不推迟执行,在执行传递回调用者之前(即之前Enumerate<T>能跑)。ReadSomeProc另一方面,在将读取器传递回调用者之前不会创建读取器,因此在读取所有值之前不会释放容器。

当你的方法使用yield return,编译器实际上更改了编译后的代码以返回IEnumerable<>, and 方法中的代码将不会运行,直到其他代码开始迭代返回的IEnumerable<>.

这意味着下面的代码甚至不会运行您的第一行Enumerate方法,然后再处理读取器并返回值。当其他人开始迭代你返回的值时IEnumerable<>,读者已经处理完毕。

using(SqlDataReader rd = cmd.ExecuteReader()){
    return rd.Enumerate<T>();
}

但是这段代码会执行整个Enumerate()方法以产生List<>返回前的结果:

using(SqlDataReader rd = cmd.ExecuteReader()){
    return rd.Enumerate<T>().ToList();
}

另一方面,无论是谁calling具有此代码的方法在计算结果之前实际上并不执行该方法:

using(SqlDataReader rd = cmd.ExecuteReader()){
    while(rd.Read())
        yield return rd.ConvertTo<T>(); //extension method wrapping FastMember
}

但是当他们执行返回的那一刻IEnumerable<>, the using块打开了,但没有打开Dispose()直到IEnumerable<>完成迭代,此时您已经从数据读取器读取了所需的所有内容。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

收益率返回与返回 IEnumerable 的相关文章

  • 将 C++ 代码(本机客户端)移植到浏览器(Web 应用程序)

    我有一个使用 Qt creator SDK 编写的 C 模块 我想将此代码移植到任何网页上运行 而不会对最终用户损害源代码 用户应该能够在任何浏览器 Chrome Firefox Safari Explorer 上看到此模块的输出 而无需安
  • 如果异常保存在 std::exception_ptr 中,那么在 catch 语句之外使用异常是否安全?

    我有一个std exception ptr其中有一个例外 我要调用std rethrow exception要获取实际的异常 catch 语句之后的异常是否有效 我的猜测是 因为我仍然持有std exception ptr它仍然有效 参见示
  • 如何使用带有进度条的 HttpClient 下载文件?

    我创建了一个名为SiteDownload并添加了一些下载图像的链接 using System Collections Generic using System Linq using System Net using System Threa
  • C++ 标准是否允许未初始化的 bool 导致程序崩溃?

    我知道一个 未定义的行为 C 几乎可以让编译器做任何它想做的事情 然而 我遇到了一次令我惊讶的崩溃 因为我认为代码足够安全 在这种情况下 真正的问题仅发生在使用特定编译器的特定平台上 并且仅在启用优化的情况下发生 我尝试了几种方法来重现问题
  • lambda 表达式到函数指针的转换

    这是这个问题的后续问题 Lambda 如何作为参数传递 https stackoverflow com questions 3321283 c0x lambda how can i pass as a parameter 据推测 MSDN
  • 运行 C# exe 文件

    复制 为什么我的 NET 应用程序在从网络驱动器运行时会崩溃 https stackoverflow com questions 148879 why does my net application crash when run from
  • 如何通过C#在SQLite数据库中写入变量DateTime值?

    我很新C and SQLite数据库并有一些变量存储在 SQLite 数据库中TimeStamp 这是我的代码 DateTime now DateTime Now m dbConnection new SQLiteConnection Da
  • 用C#发送USSD?

    我想编写一个在 Windows Mobile 6 上运行的简单 C 应用程序 它可以发送 USSD 消息 有没有任何图书馆可以帮助我做到这一点 或者是否有任何示例解释如何使用线路发送USSD http msdn microsoft com
  • const_iterators 更快吗?

    我们的编码指南更喜欢const iterator 因为它们比正常的要快一点iterator 当您使用时 编译器似乎会优化代码const iterator 这真的正确吗 如果是的话 内部到底发生了什么使得const iterator快点 编辑
  • 二元运算符重载、隐式类型转换

    class my bool private bool value public my bool bool value value value explicit operator bool return value friend my boo
  • 如何在C中递归地找到另一个字符串中的字符串位置?

    我们有一个任务来创建带有两个字符串参数的递归函数 原型应该是这样的 int instring char word char sentence 如果我们愿意调用函数 instring Word Another Word 它应该具有以下返回值
  • 具有多重继承的不明确基数

    我正在尝试在一个大库中编写一些类的子类 我收到 基础不明确 错误 这是该问题的一个可编译示例 include
  • 向窗口句柄发送消息

    我尝试使用 sendmessage 将消息从我的 C 应用程序传递到 C 我的c 代码是这样的 int tmain int argc TCHAR argv COPYDATASTRUCT cpd cpd dwData 0 LPCWSTR st
  • 从 TFS 下载工作项附件(文件已损坏)

    我正在尝试创建 C 代码 因此我可以自动从 Team Foundation Server 下载 BUGS 预定义查询的所有附件 该代码似乎工作得很好 但所有下载的文件都因意外原因而损坏 我无法查看它们 有人可以看一下代码并分享意见吗 非常感
  • Roslyn,通过 hostObject 传递值

    我正在尝试通过 hostObject 发送一个类 但显然它不想工作 using Roslyn Compilers using Roslyn Compilers CSharp using Roslyn Scripting using Rosl
  • int 类型的构造函数

    考虑到成本 这些情况是否相同 case 1 int a 5 case 2 int a 5 case 3 int a a 5 这三种语法是不同的 请耐心等待 我使用用户定义类型而不是 int 稍后我将回到 int T a 5 Direct i
  • 具有两个表的谓词构建器

    A Party可以有一个或多个Contact对象 我想选择全部Parties谁的街道名称包含特定关键字 如果我只想搜索Party我可以使用下面的代码 但我如何扩展它来搜索Contact public IQueryable
  • 在 Visual Studio C++ 资源编辑器中导入 png 文件

    我希望能够在 Visual Studio 资源编辑器中导入 png 文件 以便能够在不同的其他项目中使用嵌入的资源 有解决办法吗 我知道它适用于位图 但我对 png 感兴趣 因为即使在较低格式 16x16 或 32x32 上也可以使用 透明
  • 使用 Powershell 或 C# 获取 Azure“文件和文件夹”作业状态

    我一直在尝试找到一种方法来获取在 AzureRM 中运行的几个客户上运行的 文件和文件夹 备份作业的状态 可以在 AzureRm 门户中手动找到状态 恢复服务保管库 gt 作业 gt 备份作业 使用powershell不显示任何作业信息 G
  • 如何使用 __m128i 执行元素左移?

    我发现 SSE 移位指令只能在所有元素上移位相同的量 mm sll epi32 mm slli epi32 这些会移动所有元素 但移动量相同 http software intel com sites products documentat

随机推荐

  • Android 任务管理器或系统对话框

    我想知道有没有一种方法可以在显示系统对话框时获取事件 例如任务管理器 关闭警报 我可以通过如下意图从我的活动中关闭系统对话框 Intent closeDialog new Intent Intent ACTION CLOSE SYSTEM
  • 如何查找一个方法中调用的所有方法?

    如何在特定方法中调用其他类的方法 EXAMPLE 方法 getItem1 public String getItem1 throws UnsupportedEncodingException String a 2 a getBytes a
  • 去掉chart js折线图中的竖线

    I am using Chart js to generate maps and have customised it to a good extent But I am not able to remove the vertical gr
  • 鼠标悬停在 html 上更改图像

    我试图让图像在鼠标悬停时发生变化 这段代码适用于 IE 但不适用于其他浏览器 如 chrome opera safari 等 有什么想法吗 a href img src img login button 11 jpg a 您应该使用 ID
  • JavaScript 触发 InputEvent.isTrusted = true

    我正在尝试自动化一些任务JavaScript我需要使用InputEvent 但是当我使用正常事件时 我得到事件 isTrusted false而我的活动什么也没做 这是我的事件代码 var event new InputEvent inpu
  • JavaScript:通过类方法创建和销毁类实例

    我试图弄清楚如何通过类方法删除对象 我希望能够创建一个具有从内存中释放对象的 destroy 方法的类 到目前为止 我所做的研究还没有结论 我知道垃圾收集最终会处理该对象 但我想要一种更明确的方法来销毁它 这可能吗 class constr
  • 如何返回满足特定事件序列的行?

    我正在尝试提取满足特定事件序列的 UserID 的记录 如果用户有一个 JOIN 然后是一个后续的 CANCEL 然后是一个后续的 JOIN 我想在结果集中返回它们 我需要根据需要一次运行此查询一天 或一次运行几天 下表显示了满足和不满足该
  • 如何使用scanf限制输入长度

    在此程序中 我采用了大小为 3 4 的维字符数组 只要我每行输入 3 个字符 它就可以正常工作 例如 如果我输入abc abd abd我得到相同的输出 但如果我在第一行 第二行或第三行输入更多字母 则会出现错误 我应该如何检查二维中的空字符
  • 如何防止NFC标签克隆?

    我正在使用 NFC 标签制作一个应用程序 并且必须防止 NFC 标签被克隆 我见过许多其他 NFC 标签 当尝试克隆时 会显示弹出消息 克隆受到限制 标签由密钥保护 我希望我的 NFC 标签具有相同的安全性 这取决于您使用的标签类型以及您想
  • NSOpenPanel runModal 崩溃?

    我有一个基于此论坛上找到的代码的例程 FSRef useOpenFileToGetFSRef NSString fileName requiredFileType NSString requiredFileType FSRef fileFS
  • 轴标签与表达式的 R 对齐

    我想绘制一个变量名称及其符号 由于某些变量的名称很长 因此我尝试将换行符与轴标签混合使用 这会导致对齐中发生有趣的事情 par mar c 1 12 1 1 plot y 1 6 1 6 yaxt n ylim c 1 6 ylab axi
  • 从面板中删除关键侦听器

    是否可以清除我放在我的监听器JPanel 当我调用一个方法时 我放了一个KeyListener在面板上 但是当我退出此方法时 我想清除该侦听器 这是我的方法 private void stopBall final Graphics2D g2
  • VScode 抱怨 Java 项目没有显式编码集

    直到最近我一直使用 vscode 没有任何问题 现在没有错误出现 一些变量永远不会改变颜色 我不断收到错误消息 项目 没有明确的编码集 我不知道我需要做什么来修复它 就在几分钟前 我也遇到了同样的问题 这是我修复它的方法 单击齿轮图标 单击
  • 更新 cabal-install,但版本没有改变

    目前我正在使用 cabal install 1 16 0 我尝试更新 cabal install 因为有人告诉我有更新版本的 ghc 7 6 1 可用 除了这条消息之外 安装结果非常成功 警告 无法在 Users MyName Librar
  • 对 flatList 中的项目进行排序

    在我的 React Native 应用程序中 我显示了我的办公室提供的服务以及这些服务在平面列表中的位置 我还在同一个公寓列表中显示了从该人当前地址开始的服务里程 我希望这些服务按里程排序 下面是我的屏幕数据 以下地点提供服务 123 Te
  • 将 ftable(列联表)转换为 R 中的数据帧

    我正在生成一个ftable 通过在xtabs命令的结果上运行ftable 并且我得到以下内容 Var1 Var2 date group 2007 01 01 q1 1 9 q2 2 8
  • @jsonview of jackson 不使用 jax-rs

    我写了以下代码 class A public static class Public Entity class public class B JsonView A Public class int a int b public class
  • 如何强制关闭串口连接?

    我有通过 USB 串行通信连接到 PC 的设备 我正在执行以下步骤 启动设备 开机 设备将在我的 PC 中检测为 COMx 名称 开始我的申请 基于COM PID VID 我连接到设备 进行沟通 到目前为止我没有遇到任何问题 当我关闭设备时
  • 接口的扩展方法的优先级是否低于不太具体的扩展方法?

    我有以下扩展类 public static class MatcherExtensions public static ExecMatcher
  • 收益率返回与返回 IEnumerable

    我注意到阅读时有一些好奇的事情IDataReader在我无法理解的 using 语句中 虽然我确信答案很简单 为什么在里面时using SqlDataReader rd 如果我直接执行yield return阅读器在阅读期间保持打开状态 但