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

使用反射修改泛型Dictionary条目值后字典取值未更新问题

问题解决:反射修改Dictionary Entry值后dict[key]仍返回原值的原因及修复

核心原因

你遇到的问题根源在于:.NET中Dictionary<TKey,TValue>的内部Entry是值类型(struct)。当你通过((Array)dict.GetField(...).GetValue(dict)).GetValue(0)获取entry时,得到的是该结构体的副本,而非原数组中元素的引用。因此你修改的只是这个副本的value字段,原数组里的真实Entry完全没被改动,自然通过dict[key]访问时还是原值。

修复方案

要修改原数组中的Entry,需要先获取整个entries数组,取出对应索引的结构体实例,修改其value后,再将修改后的结构体重新赋值回数组的对应位置。

修正后的测试代码

const BindingFlags BINDING_FLAGS_ALL = (BindingFlags)65535;
Dictionary<string, string> dict = new Dictionary<string, string>();
dict["key1"] = "original value";

// 获取entries数组
Array entriesArray = (Array)dict.GetType().GetField("entries", BINDING_FLAGS_ALL).GetValue(dict);
// 获取指定索引的Entry(值类型,此时是副本)
object entry = entriesArray.GetValue(0);

// 获取key和value字段
object key = entry.GetType().GetField("key", BINDING_FLAGS_ALL).GetValue(entry);
FieldInfo valField = entry.GetType().GetField("value", BINDING_FLAGS_ALL);

Console.WriteLine($"original value at '{key}' == '{valField.GetValue(entry)}'");

// 修改副本的value
valField.SetValue(entry, "changed value!");
Console.WriteLine($"new value in copied entry == '{valField.GetValue(entry)}'");

// 将修改后的副本放回原数组
entriesArray.SetValue(entry, 0);

// 现在通过dict[key]获取就能得到新值了
object val = dict[(string)key];
Console.WriteLine($"dict[{key}] == '{val}'");

输出结果

original value at 'key1' == 'original value'
new value in copied entry == 'changed value!'
dict[key1] == 'changed value!'

额外说明

因为你不知道字典的Key和Value类型,上述代码完全基于反射操作,不需要依赖具体的泛型类型,同样适用于任意Dictionary<TKey,TValue>实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:18:22