通过反射获取IDictionary项目值设置器

时间:2018-11-16 05:40:27

标签: c# dictionary reflection idictionary

我正在尝试获取字典项目值的setter函数。我知道对象是Dictionary ,但是我不知道Tkey和TValue的类型,所以我认为我唯一的方法是使用IDictionary。

在伪代码中,我想做这样的事情;

Action<object> keySetter = dictionary.items[index].value.setter
Action<object> valueSetter = dictionary.items[index].key.setter

不幸的是,IDictionary没有索引器,我不确定如何获取实际的键和值。

现在,我正在遍历字典条目并从中获取设置器,但是每当我调用设置器时,它似乎都不会改变字典中的值。因此,我怀疑DictionaryEntry是副本,并且未指向字典中的实际值。

//for simplicity sake a Dictionary is added here, but usually the TKey and Tvalue are not known
IDictionary target = new Dictionary<int, string>();
target.Add( 0, "item 1" );

foreach ( DictionaryEntry dictionaryEntry in target )
{
    //want to get the setter for the item's key setter and value setter
    PropertyInfo keyProperty = dictionaryEntry.GetType().GetProperty( "Key" );
    PropertyInfo valueProperty = dictionaryEntry.GetType().GetProperty( "Value" );

    Action<object> keySetter = ( val ) =>
    {
        keyProperty.SetMethod.Invoke( dictionaryEntry, new object[] { val } );
    };

    Action<object> valueSetter = ( val ) =>
    {
        valueProperty.SetMethod.Invoke( dictionaryEntry, new object[] { val } );
    };

    keySetter.Invoke( 1 );
    valueSetter.Invoke( "item 1 value succesfully modified" );

    Console.WriteLine( target.Keys ); //no change
    Console.WriteLine( target.Values ); //no change
}

由于我确实知道IDictionary实际上是下面的Dictionary ,也许我可以做一些反射魔术来以这种方式获取二传手?

1 个答案:

答案 0 :(得分:0)

枚举Dictionary的条目时,KeyValueDictionary的内部结构(Entry[])复制到{ {1}}或KeyValuePair。因此,尝试修改这些DictionaryEntry是徒劳的,因为这些更改不会传播回字典。要修改DictionaryEntry,您必须使用它的索引器或DictionaryAdd或类似方法。

C#索引器只是使用Dictionary<TKey,TValue>.Item属性的语法糖。因此,在使用反射时,必须改为使用此属性。

要为Remove中的每个项目创建值设置器,您需要获取每个项目的键,然后在将新值设置为{{1]时将其用作Dictionary自变量}}使用它的index属性。创建密钥设置器更加困难,因为Dictionary不支持更改现有密钥。您要做的实际上是从Item中删除现有项目,并使用新密钥插入一个新项目:

Dictionary