遍历字典,同时修改其值但不是其键

问题描述

还有一些其他问题与这个主题有关,但似乎没有一个能解决它(或者,它们太复杂了,我无法理解它们......)

我有一个:

Private MCDevices As New Dictionary(Of IPAddress,MCDeviceInfo)

在这个 Dictionary 中,IPAddress 是键(显然),而 MCDeviceInfo 是在其他地方定义的 Classes。所以它基本上是一个 Dictionnary(Of IPAddress,Class)

我想通过 For ... Next 执行 MCDevices Dictionary 循环,在该循环中,我更改了 MCDeviceInfo Classes 的内容:在循环中,我更改了 values 的 KVP,但没有以任何方式在循环中添加、更改或删除 IPAddress,我再次检查了这一点。

For Each kvp As KeyValuePair(Of IPAddress,MCDeviceInfo) In MCDevices
' Some code changing the contents of the MCDeviceInfo but not the IPAddress
Next

仍然到达 Next,我得到:

**System.InvalidIperationException:** 'Collection was modified; enumeration operation may not continue'.

这里的条件可能非常乐观,因为代码就停在那里......

有没有办法解决这个问题?为什么我不能在键不变的情况下更改值?

解决方法

可以更改这些值。考虑以下代码并将其与您的密码进行比较:

Imports System.Net

Module Module1

    Private MCDevices As New Dictionary(Of IPAddress,MCDeviceInfo)

    Public Class MCDeviceInfo
        Property Name As String
        Property Vegetarian As Boolean

        Public Overrides Function ToString() As String
            Return $"Name: {Name}"
        End Function
    End Class

    Sub Main()
        MCDevices.Add(IPAddress.Parse("1.1.1.1"),New MCDeviceInfo With {.Name = "Burger",.Vegetarian = False})
        MCDevices.Add(IPAddress.Parse("1.1.1.2"),New MCDeviceInfo With {.Name = "Beanburger",.Vegetarian = True})
        MCDevices.Add(IPAddress.Parse("1.1.1.3"),New MCDeviceInfo With {.Name = "Fries",.Vegetarian = True})

        For Each mcd In MCDevices
            If mcd.Value.Vegetarian Then
                mcd.Value.Name &= " Supersize"
            End If
        Next

        Console.WriteLine(String.Join(vbCrLf,MCDevices))
        Console.ReadLine()

    End Sub

End Module

输出:

[1.1.1.1,Name: Burger]
[1.1.1.2,Name: Beanburger Supersize]
[1.1.1.3,Name: Fries Supersize]
,

根据@AndrewMorton、@Jimi 和@JayV 和@jmcilhinney 的输入,我现在认为 替换值,因此替换 MCDeviceInfo Classes,而不仅仅是更改它们的属性,可能是问题所在。

此外,我现在知道以下操作不起作用:

For Each kvp As KeyValuePair(Of IPAddress,MCDeviceInfo) In MCDevices
  ' Some code that changes the properties of the MCDeviceInfo Classes and even
  ' replaces them although the keys,the IPAddresses,are not touched in any way.
Next ' fails on the Next with the error mentioned in my question.

但是下面的确实有效(本质上是@Justin R.在他的回答中写的内容的翻译,@JayV在他对我最初的问题的评论中链接到):

Dim keys As List(Of IPAddress) = MCDevices.Keys.ToList
For Each key As IPAddress In keys ' Loop over the IPAddress,the keys of the KVP
  ' Some code that changes the properties of the MCDeviceInfo Classes and even
  ' replaces them.
Next

事实证明,For Each 完全可以,就像普通的 For...Next 一样。在第二个版本中,循环在一个完全独立的列表 keys 上。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...