使用反射设置通用字典中的条目值

问题描述 投票:0回答:2

我正在尝试使用 System.Reflection 修改通用字典中的值,但我不知道 IKey 和 IValue 的类型。 我可以使用一系列 GetField()、GetValue() 和 SetValue() 语句(下面的代码)为字典中的每个条目设置 Dictionary.Entry.value 的值,但是 dict[key 返回的值] 仍然返回未改变的值。

这是我想要做的简单示例(真正的代码在此之后):

dict["some key"] = "some value";
// Use reflection to do a SetValue dict.entries[0] to "some new value"
Printing out dict["some key"] should now display "some new value"

相反,它打印出原始值。 在下面的代码中,您将看到键是匹配项,并且在 SetValue() 检索新值之后调用 GetValue()。 我不知道为什么会发生这种情况。

这是代码:

const BindingFlags BINDING_FLAGS_ALL = (BindingFlags) 65535;
Dictionary<string, string> dict = new Dictionary<string, string>();
dict["key1"] = "original value";
object entry = ((Array) dict.GetType().GetField("entries", BINDING_FLAGS_ALL).GetValue(dict)).GetValue(0);
object key = entry.GetType().GetField("key", BINDING_FLAGS_ALL).GetValue(entry);
FieldInfo val_field = entry.GetType().GetField("value", BINDING_FLAGS_ALL);
object val = val_field.GetValue(entry);
Console.WriteLine($"original value at '{key}' == '{val}'");
val_field.SetValue(entry, "changed value!");
val = val_field.GetValue(entry);
Console.WriteLine($"new value at '{key}' == '{val}'");
val = dict[(string) key];
Console.WriteLine($"dict[{key}] == '{val}'");

输出为:

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

提前感谢您的指导! DD

c# reflection system.reflection
2个回答
0
投票

每种具有索引器的类型还包含隐藏方法:

get_Item
set_Item

我的方法是通过反射调用

set_Item
方法:

Dictionary<string, string> dict = new Dictionary<string, string>();
dict["key1"] = "original value";
var type = dict.GetType();
var setItemMethod = type.GetMethod("set_Item");
setItemMethod.Invoke(dict, new object[] { "key1", "changed value!" });
Console.WriteLine(dict["key1"]);

该程序将显示输出

changed value!

它甚至适用于您不知道其类型的字典,只需将此方法更改为任何类型即可:

setItemMethod.Invoke(dict, new object[] { 10, 50 }); // for integers

小提琴


0
投票

Entry
是一个 struct

因此您正在使用它的副本,而不是 Dictionary 内部使用的副本。

© www.soinside.com 2019 - 2024. All rights reserved.