在 C# 中枚举时从 List 中删除项目的智能方法

2024-05-07

我有一个经典的案例,尝试从集合中删除一个项目,同时在循环中枚举它:

List<int> myIntCollection = new List<int>();
myIntCollection.Add(42);
myIntCollection.Add(12);
myIntCollection.Add(96);
myIntCollection.Add(25);

foreach (int i in myIntCollection)
{
    if (i == 42)
        myIntCollection.Remove(96);    // The error is here.
    if (i == 25)
        myIntCollection.Remove(42);    // The error is here.
}

在发生更改后的迭代开始时,InvalidOperationException被抛出,因为枚举器不喜欢底层集合发生变化。

我需要在迭代时对集合进行更改。有许多可用于避免这种情况的模式,但他们似乎都没有一个好的解决方案:

  1. 不要在此循环内删除,而是保留一个单独的“删除列表”,在主循环之后处理。

    这通常是一个很好的解决方案,但就我而言,我需要该项目立即消失,因为“等待”直到之后 真正删除该项目的主循环改变了我的代码的逻辑流程。

  2. 无需删除该项目,只需在该项目上设置一个标志并将其标记为非活动状态即可。然后添加模式1的功能来清理列表。

    This would满足我所有的需求,但这意味着lot的代码必须更改,以便每次访问项目时检查非活动标志。对于我来说,这实在是太多的管理工作了。

  3. 以某种方式将模式 2 的思想合并到派生自的类中List<T>。该超级列表将处理非活动标志、事后删除对象,并且不会向枚举使用者公开标记为非活动的项目。基本上,它只是封装了模式 2(以及随后的模式 1)的所有思想。

    存在这样的类吗?有人有这方面的代码吗?或者,还有更好的方法?

  4. 有人告诉我访问myIntCollection.ToArray()代替myIntCollection将解决问题并允许我在循环内删除。

    对我来说,这似乎是一个糟糕的设计模式,或者也许还不错?

Details:

  • 该列表将包含许多项目,我将仅删除其中一些。

  • 在循环内,我将执行各种过程,添加、删除等,因此解决方案需要相当通用。

  • 我需要删除的项目may not是循环中的当前项。例如,我可能位于 30 项循环的第 10 项上,需要删除第 6 项或第 26 项。因此,向后遍历数组将不再起作用。 ;o(


最好的解决方案通常是使用RemoveAll() https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.removeall method:

myList.RemoveAll(x => x.SomeProp == "SomeValue");

或者,如果您需要certain删除的元素:

MyListType[] elems = new[] { elem1, elem2 };
myList.RemoveAll(x => elems.Contains(x));

当然,这是假设您的循环仅用于删除目的。如果你do需要额外的处理,那么最好的方法通常是使用for or while循环,从那时起你就不再使用枚举器:

for (int i = myList.Count - 1; i >= 0; i--)
{
    // Do processing here, then...
    if (shouldRemoveCondition)
    {
        myList.RemoveAt(i);
    }
}

向后移动可确保您不会跳过任何元素。

对编辑的回应:

如果您要删除看似任意的元素,最简单的方法可能是只跟踪要删除的元素,然后立即将它们全部删除。像这样的事情:

List<int> toRemove = new List<int>();
foreach (var elem in myList)
{
    // Do some stuff

    // Check for removal
    if (needToRemoveAnElement)
    {
        toRemove.Add(elem);
    }
}

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

在 C# 中枚举时从 List 中删除项目的智能方法 的相关文章

  • 不同提供商的相同 EDMX 文件

    我正在开发一个项目 其中有一个本地数据库 SQL CE 在不存在与服务器的连接的情况下用作缓冲区 在服务器上我想使用相同的数据库布局 当然 我想使用服务器和客户端上可用的 Common dll 中的相同 EDMX 文件 在客户端中 我有一个
  • C# 中直接从 URL 获取图像尺寸

    我正在尝试使用以下代码直接从网络上获取图片的尺寸 string image http www hephaestusproject com csharp3 png byte imageData new WebClient DownloadDa
  • C++0x 初始值设定项列表示例

    我想看看这个现有代码示例如何利用 C 0x 初始化列表功能 示例0 include
  • JetBrains Rider 针对 4.5 框架,无法切换到 4.7

    基本上 当尝试添加不支持旧框架的 NuGet 包时 会出现错误 但是在项目配置中只有 4 5 可用 在项目创建过程中 不存在选择目标的选项 有什么方法可以正确配置它吗 I haven t found out how to set up NE
  • 在异步请求中使用超时回调

    我之前问过这个问题 但我将用提出的解决方案来完成这个问题 并提出另一个问题 我正在使用这个类来进行异步网络请求 http msdn microsoft com en us library system net webrequest aspx
  • C# 实体框架我们应该使用 POCO.Id 还是仅使用 POCO 设置关系?

    我在服务方法中遇到一种情况 将 POCO 分配为另一个 POCO 的子对象无法按预期工作 我正在使用实体框架 4 public void ChangeOrderCurrency Currency currency order Currenc
  • 为什么我在 WinForms 列表框中得到“System.Data.DataRowView”而不是实际值?

    每当我运行代码并尝试查看highscore我在列表框中得到的只是System Data DataRowView 谁能明白为什么吗 Code MySqlConnection myConn new MySqlConnection connStr
  • 打开位置设置页面或提示用户启用位置

    我一直在绞尽脑汁 徒劳地谷歌搜索 我正在尝试找到一种方法来提示用户通过直接进入设置页面或仅点击屏幕上的 是 来切换位置 我见过的所有代码似乎都不起作用 有人有有效的方法吗 一个详细的例子将不胜感激 谢谢 我对 Xamarin 开发非常陌生
  • 根据 Active Directory 策略检查密码[重复]

    这个问题在这里已经有答案了 我有一个允许用户更改其 AD 密码的前端 有没有办法获取特定用户及其属性 长度 复杂性 的密码策略 例如细粒度 有没有办法根据此特定策略检查字符串 xyz121 编辑 我不想检查活动目录中存储的当前密码 我想检查
  • 从二进制文件读取字节到 long int

    我有两个问题 我有二进制文件的数据 我想使用 read 函数读取前 8 个字节以签署 long int 但我不能 你知道我该怎么做吗 如何直接读取一块数据到字符串中 我可以像所示那样阅读吗 前任 ifstream is is open te
  • C# 反序列化过程中创建指向父对象的指针

    我有这样的课程 Serializable public class child public Parent parent Serializable public class Parent public List
  • 这些工作队列标志意味着什么?

    在研究工作队列时 我遇到了内核中定义的工作队列标志和常量 我有以下我无法理解的疑问 这里的排水和救援到底是什么意思 WQ DRAINING 1 lt lt 6 internal workqueue is draining WQ RESCUE
  • 使用联合对 IP 地址进行多种解释?

    在工作中 我们使用以下构造来将 IP 地址解释为 4 字节数组或 32 位整数 union IPv4 std uint32 t ip std uint8 t data 4 这很好用 但是读完这本书的第 97 章 不要使用联合来重新解释表示
  • XCode std::thread C++

    对于学校的一个小项目 我需要创建一个简单的客户端 服务器结构 它将在路由器上运行 使用 openWRT 并且我试图在这个应用程序中使用线程做一些事情 我的 C 技能非常有限 所以我在internet https stackoverflow
  • 如何阻止 Control-I 在 CoreWindow 范围内的 UWP 文本框中插入选项卡?

    当我在 UWP 应用程序中有一个 TextBox 时 对我来说 奇怪的行为 在 Windows 10 中创建通用的空白应用程序 UWP 应用程序 使用以下代码将文本框添加到默认网格
  • 如何在 SQLite 中检查数据库是否存在 C#

    我目前正在用 C 编写一个应用程序 并使用 sqlite 作为嵌入式数据库 我的应用程序在启动时创建一个新数据库 但如何让它检查数据库是否存在 如果它确实存在 我如何让它使用它 如果不存在如何创建一个新数据库 这是我到目前为止所拥有的 pr
  • 使用 WinAPI 连接禁用的显示设备

    我的问题是启用禁用的监视器ChangeDisplaySettingsEx 我想这不是火箭科学 但经过一番挖掘后 它看起来仍然是不可能的 我找到了一种根据找到的 Microsoft 代码示例禁用所有辅助显示器的方法here https msd
  • C# 模式匹配

    我对 C 有点陌生 我正在寻找一个字符串匹配模式来执行以下操作 我有一个像这样的字符串 该书将在 唐宁街 11 号接待处 并将由主要医疗保健人员参加 我需要创建一个 span 标签来使用 startIndex 和 length 突出显示一些
  • 如何创建实体集或模型而不在数据库中创建相应的表 - 实体框架

    我的 sqlserver 数据库中有一个存储过程 它返回多个结果集 我正在使用 msdn 中的以下链接从实体框架中的 SP 读取多个结果集 https msdn microsoft com en us library jj691402 v
  • 查找和替换正则表达式问题

    感谢这里对我其他问题的所有大力帮助 我开始掌握正则表达式 但我仍然对这个一无所知 我的代码是 StreamReader reader new StreamReader fDialog FileName ToString string con

随机推荐

  • 找不到“Attributes.inc”文件

    我一直在使用中提供的标题include llvm and include llvm c尝试制作我自己的编译器 但是 每当我尝试编译时 都会收到此错误 没有llvm IR Attributes inc在我的文件或我见过的任何 LLVM 项目中
  • 将 Django 模型映射到外部 API

    上下文 我有一个外部 API 提供数据并允许发布新数据或修补现有数据 API 响应示例 response requests get http api band 4 print response json id 4 name The Beat
  • 更改 NSIS 安装程序属性

    我有一个基于 NSIS 的安装程序文件 名为安装程序 当我进入 属性 gt 详细信息 时 缺少许多详细信息 当我运行安装程序时 UAC 请求提升权限 这是可以的 但发布者是 未知 我如何在最终设置这些属性安装程序 最好只更改 NSIS 安装
  • XAMPP无法安装xdebug

    你好 我已经安装了 xampp 将 php ini 更改为 XDebug zend extension C xampp php ext php xdebug 2 2 3 5 3 vc9 dll xdebug profiler append
  • 单选按钮文本对齐问题

    我正在 asp net 中工作 并且有单选按钮列表 我想根据需要对齐它们的文本 这是我目前拥有的 我想让它们像这样 EDIT 其次 当我单击 Ages From 单选按钮时 我会显示一个 div 如下所示 当我单击返回 All Ages 单
  • 有没有办法检测 Alt 键被按在哪一侧(右或左)?

    Is there a way that we can detect which side the Alt key was pressed on i e distinguish between left or right Alt I saw
  • GWT:将自定义小部件添加到单元格丢失自定义小部件的事件

    我们的要求是使用以下命令制作一个可编辑的网格CellTable在其单元格中包含自定义小部件 自定义小部件具有文本框和与文本框关联的搜索按钮 要将自定义小部件添加为单元格 请创建以下子类AbstractEditableCell类 由 GWT
  • 使用 Moq 模拟实体框架 6 ObjectResult

    如何使用 Moq 模拟 Entity Framework 6 ObjectResult 以便对依赖 EF 数据库连接的代码进行单元测试 沿着这些思路阅读了大量的问题和答案 并从我所读到的内容中收集了许多有价值的信息 我已经实现了我认为相当优
  • 在 tidycensus 中使用 purrr() 而不是 lapply 任意城市/县对?

    我有一个巨大的 lapply 正在运行来下载数据文件 但看起来很笨拙 但 mapply 似乎不对 因为我不想要所有州 县的组合 我听说过关于 map 的好消息 任何人都可以提供一个示例 说明如何在以下代码中使用 purrr 命令 map l
  • 是否可以使用 Drupal api 获取用户列表?

    我想获取已分配特定角色的所有用户的列表 我可以编写自己的 SQL 但我想尽可能多地使用 api 您可以使用entity load来获取用户数组 这是将为管理员用户创建所有电子邮件列表的示例 用于发送通知
  • Asp net Core 获取用户Windows用户名

    在ASP net CORE mvc中构建内联网 我需要获取当前用户的Windows用户名进行登录 我不需要使用Windows身份验证自动登录用户 我已经有一个自定义登录控制器来做到这一点 我只需要他的用户名 它在本地工作正常 但在 IIS
  • @Service 中带有 Kotlin 的 Spring Boot @Autowired 始终为 null

    目前 我尝试使用 Kotlin 重写我的 Java Spring Boot 应用程序 我遇到了一个问题 在我所有的类中都用 Service依赖注入无法正常工作 所有实例都null 这是一个例子 Service Transactional o
  • 每行仅显示 3 个 foreach 结果

    我的脚本如下 output table class products tr while info mysql fetch array data Outputs the image and other data output td img s
  • 如何保护 Hibernate QBE 查询的安全

    目前 我知道四种使用 hibernate 进行事务处理的方式 使用对象 使用HQL 使用特定于数据库的 SQL 使用标准 QBE 好吧 关于它们对注射的抵抗力有多强 我认为是这些 如果我错了 请纠正我 安全 因为内部 SQL 调用是参数化的
  • alter Windows 文件中的 krb5.ini 文件哪里去了?

    至少在 Windows XP 之前 如果您加入具有 Kerberos 领域特定设置的域 就会有一个 krb5 ini 文件 从 Vista 或 7 开始 不再需要此文件 我试图找到有关此的更多信息 但陷入困境 krb5 ini 文件中的设置
  • 什么时候会在 dict 上使用键值对作为 dict.update 方法?

    我注意到你可以做两件事来更新字典 并且它们似乎有相同的结果 a a update foo 1 a a update foo 1 两者都会产生如下所示的字典结果 foo 1 是否有任何理由更喜欢使用字典或键 值对作为更新方法 它们在功能上是否
  • PostgreSQL 对 string\varchar 的各种清理

    我必须通过以下方式清理一些 varchar 删除特殊字符 例如 来自封闭列表 我已经成功地通过大量使用replace regexp replace来做到这一点 但我正在寻找类似于SQL Server中的东西 删除以下数字但不删除相邻的数字含
  • 如何在hybris中添加元描述?

    截屏 https i stack imgur com r7feW jpg我可以看到可以添加元标题的位置 但看不到任何元描述列 您可以调试ProductPageController在那里您可以看到如何设置元描述 在 Hybris OOTB 我
  • Javascript - 如何从 location.href 中删除域

    我需要使用 Javascript 从 location href 中删除域名 我有类似的链接 http localhost App User UserOrder aspx id 949abc91 a644 4a02 aebf 96da3ac
  • 在 C# 中枚举时从 List 中删除项目的智能方法

    我有一个经典的案例 尝试从集合中删除一个项目 同时在循环中枚举它 List