You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于现有Dictionary创建新字典得到非预期结果问题咨询

问题根源

这个问题和ByVal/ByRef的差异无关,是引用类型传递的特性导致的:

  • .NET中List(Of T)属于引用类型,代码中传递的不是列表的副本,而是指向堆中实际列表对象的内存引用。
  • 你的appendToDict方法中,当新字典不存在对应key时,直接把原始字典里的List引用作为值添加到了新字典中,后续对新字典中这个List的修改,实际就是修改原始字典里的List对象。

异常执行流程梳理

  1. 第一次循环处理2018对应的列表[User1,User2,User3]:
    • 调用appendToDict("Users", 2018年列表, newDictionary),此时新字典没有Users键,直接把2018年的原始列表引用赋值给newDictionary("Users")
    • 接着调用appendToDict("Alpha", 2018年列表, newDictionary),同样直接把2018年原始列表引用赋值给newDictionary("Alpha")
  2. 后续处理2019、2020年的列表时:
    • 调用appendToDict("Users", 对应年份列表, newDictionary)时,Users键已经存在,会把后续年份的用户全部AddRange到newDictionary("Users")对应的列表里
    • 但因为newDictionary("Users")实际指向的就是2018年的原始列表,所以这一步相当于直接修改了原始字典里2018年对应的列表内容,同时newDictionary("Alpha")也指向同一个列表,所以Alpha列表也跟着变成了全部7个用户,原始字典也被意外修改。

修复方案

修改appendToDict方法,当key不存在时,添加的是原始列表的副本而不是原始引用:

Private Sub appendToDict(key As String, val As List(Of String), dict As Dictionary(Of String, List(Of String)))
    If dict.ContainsKey(key) Then
        dict(key).AddRange(val)
    Else
        ' 这里创建新列表拷贝原始数据,不再共用引用
        dict.Add(key, New List(Of String)(val))
    End If
End Sub

修改后所有新字典里的列表都是独立的对象,不会再互相影响,也不会修改原始字典的数据。

内容的提问来源于stack exchange,提问作者clarkcone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 15:24:03