为什么这个方法会导致无限循环?

2024-03-19

我的一位同事向我提出了关于这种导致无限循环的方法的问题。实际的代码有点复杂,无法在这里发布,但本质上问题归结为:

private IEnumerable<int> GoNuts(IEnumerable<int> items)
{
    items = items.Select(item => items.First(i => i == item));
    return items;
}

This should(您可能会认为)只是创建列表副本的一种非常低效的方法。我用以下方式调用它:

var foo = GoNuts(new[]{1,2,3,4,5,6});

结果是无限循环。奇怪的。

我认为修改参数在风格上是一件坏事,所以我稍微改变了代码:

var foo = items.Select(item => items.First(i => i == item));
return foo;

那行得通。即程序完成;没有例外。

更多实验表明这也有效:

items = items.Select(item => items.First(i => i == item)).ToList();
return items;

就像一个简单的

return items.Select(item => .....);

Curious.

很明显,问题与重新分配参数有关,但前提是评估被推迟到该语句之外。如果我添加ToList()有用。

我对出了什么问题有一个大致的、模糊的想法。它看起来像Select正在迭代它自己的输出。这本身有点奇怪,因为通常IEnumerable如果正在迭代的集合发生变化,将会抛出异常。

我不明白的是,因为我不太熟悉这个东西的工作原理,所以重新分配参数会导致这个无限循环。

有没有更了解内部原理的人愿意解释为什么这里会发生无限循环?


回答这个问题的关键是延迟执行。当你这样做时

items = items.Select(item => items.First(i => i == item));

you do not迭代items数组传递到方法中。相反,您为其分配一个新的IEnumerable<int>,它引用自身,并且仅当调用者开始枚举结果时才开始迭代。

这就是为什么你的所有其他修复都解决了这个问题:你所需要做的就是停止喂食IEnumerable<int>回到自身:

  • Using var foo通过使用不同的变量来打破自引用,
  • Using return items.Select...根本不使用中间变量来破坏自引用,
  • Using ToList()通过避免延迟执行来打破自引用:到时候items被重新分配,旧的items已经被迭代了,所以你最终会得到一个简单的内存List<int>.

但如果它以自身为食,它是如何获得任何东西的呢?

没错,它什么也没得到!当你尝试迭代的那一刻items并询问第一个项目,延迟序列询问提供给它的序列以处理第一个项目,这意味着该序列正在询问自己要处理的第一个项目。此时,就是海龟一路下来 https://en.wikipedia.org/wiki/Turtles_all_the_way_down,因为为了返回要处理的第一个项目,序列必须首先从其自身获取要处理的第一个项目。

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

为什么这个方法会导致无限循环? 的相关文章

  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • 重载<<的返回值

    include
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK

随机推荐

  • iPad 方向仅限纵向

    我将项目摘要 gt iPhone iPod 部署信息 gt 支持的界面方向设置为仅纵向模式 这适用于所有模拟器 iPad iOS 5 1 和 iPhone iOS 6 1 但是当我将 iPad 上的 iOS 从 5 1 升级到 6 1 2
  • Xcode 7.0 Beta 4 的 GameCenter 框架图像未找到错误

    当尝试使用 Xcode 7 Beta 4 在实际 iPhone iOS 版本 8 4 上运行应用程序时 是否有人遇到此问题 dyld 库未加载 System Library Frameworks GameCenter framework G
  • React Native atob() / btoa() 在没有远程 JS 调试的情况下无法工作

    我有一个反应本机测试应用程序 当我远程启用调试js时 一切正常 运行后 它在设备 来自 XCode 和模拟器中运行良好 react native run ios 问题是 如果我停止远程 js 调试 登录测试将不再起作用 登录逻辑非常简单 我
  • 谷歌纸板 VR 传感器

    我正在使用谷歌纸板 its HeadTracker类 来检测 AR 应用程序中有关设备旋转的某些事情 它运作得很好 但是 在某些设备上 它不起作用 什么也没有发生 我认为这是因为他们没有必要的传感器 我的问题 1 我想在运行时检测当前设备是
  • 如何将文件重置或恢复到特定版本?

    如何在特定的提交哈希 我通过确定 将修改后的文件恢复到之前的版本git log https git scm com docs git log and git diff https git scm com docs git diff 假设您想
  • 更改背景颜色后如何保存 Matplotlib 图形?

    使用 Spyder IDE 我创建了一个 matplotlib 图 并将图形对象和轴对象的面 背景 颜色更改为黑色 当我尝试使用保存图形时plt savefig 不包括坐标区 标题和坐标区标签 我尝试过实施标准建议 https stacko
  • 如何以 0,00 格式显示价格(即一百 100,00)

    hii 我正在使用 devexpress 网格控件 在我的网格中有价格选项卡 因为我希望价格列以 0 00 格式显示 即如果我的价格是 3000 那么它应该显示 3 000 00 请帮助我 它是针对 winforms 的 前端是 c Dev
  • 如果库需要不同版本的“base”该怎么办?

    我正在尝试安装需要与我已安装的版本不同的基础版本的软件包 我有4 6 0 0 他们要求 lt 4 6 我如何在我的系统上安装这些 编辑 这些包实际上需要较旧的包才能构建 而不仅仅是作为 cabal 约束 由于无法重新安装base 在更新之前
  • C# 中的 const 字节字段按位 NOT

    我意识到 如果我有一个 byte 类型的字段或变量 我可以对其应用按位 NOT 并将其转换为字节 但是 如果该字段是 const byte 我仍然可以应用按位 NOT 但无法将其转换为字节 例如 这编译 class Program byte
  • 我可以从 LotusScript 函数返回列表吗?

    我想从 LotusScript 中的函数返回一个列表 eg Function myfunc List As Variant Dim mylist List As Variant mylist one 1 mylist two 2 myfun
  • 在 Windows Phone 8 中使用 App.Current.Terminate() 方法

    由于Windows Phone 8为我们提供了这种以编程方式终止应用程序的方法 如果我们在应用程序中使用此方法在导航历史记录中没有回溯条目的情况下终止页面 那么在提交应用程序时会出现任何问题吗 使用此调用时 认证不会有任何问题 但请确保在调
  • 上传 zip 和 rar 文件在 codeigniter 中不起作用

    我为允许的类型创建的设置 config allowed types doc docx pdf xls xlsx rtf txt rar zip 在我的mine php中 zip gt array application x zip appl
  • Cordova 构建:请安装 Android 目标:“android-22”。我不想要 android-22。我想要 android-19 - 我该怎么办?

    我正在努力解决我的phonegap 设置和构建我的第一个应用程序 我创建了一个 hello1 项目 我添加了android项目 平台android已经添加 现在 当我运行 cordova 构建时 我收到错误 错误 请安装 Android 目
  • 如何使用 Apache CXF 以简单的方式获取传入和传出的soap xml?

    我一直在 CXF 上摆弄服务器端拦截器 但实现简单的传入和传出拦截器 为我提供包含 SOAP XML 的纯字符串 似乎并不是一项简单的任务 我需要在拦截器中包含纯 XML 以便我可以将它们用于特定的日志记录任务 标准的 LogIn 和 Lo
  • 重定向到从 json 响应获取的 url

    我正在使用 jquery ajax 方法向 php 网页发出 http 请求 作为响应 我采用像 status success url http url 这样的 json 在成功函数上 我从 json 重定向到 url 但大多数时候它都会失
  • iOS UINavigationBar vs UIToolbar vs UITabBar

    让我知道在什么情况下应该使用哪一个 它们之间有什么区别 每个组件的优点和缺点是什么 The UI导航栏类实现用于导航分层内容的控件 它是一个栏 通常显示在屏幕顶部 包含用于在层次结构中上下导航的按钮 主要属性是左 后 按钮 中心标题和可选的
  • 将请求转发到弹簧控制器

    从 servlet 我将请求转发到 spring 控制器 如下所示 RequestDispatcher rd request getRequestDispatcher myController test reqParam value rd
  • Elisp 交互功能,具有输入历史记录

    有很多交互式函数将字符串输入作为参数 defun zb run cmd X arg1 argN interactive Marg1 Marg2 some logic 如何制作每个这样的功能zb run cmd 1 zb run cmd N
  • 同时设置jtextfield textlimit和大写

    我的应用程序中有几个 jtextfield 我想将其中一个允许大写和小写 并限制可以引入 jtextfield 的字符数 我必须区分类别 一个用于放置限制 另一个用于放置大写或小写 jtextfield限制的代码 package teste
  • 为什么这个方法会导致无限循环?

    我的一位同事向我提出了关于这种导致无限循环的方法的问题 实际的代码有点复杂 无法在这里发布 但本质上问题归结为 private IEnumerable