添加到反映的词典

时间:2018-05-17 11:43:43

标签: c#

我有一个看起来像这样的遗留类:

public class LegacyBusinessObject
{
....(100 similar fields in total)
    public Dictionary<string, string> SomeBusinessValue1 = new Dictionary<string, string>();
    public Dictionary<string, long> SomeBusinessValue2 = new Dictionary<string, long>();
    public Dictionary<string, decimal> SomeBusinessValue3 = new Dictionary<string, decimal>();
....
}

而字符串键表示提供者此值来自。

因此对于上下文:&#34; SomeBusinessValue1&#34;可能是一种体重测量,根据实验室的不同而不同。

我想使用反射将其中几个怪物合并到一个对象中:

    public LegacyBusinessObject Merge(Dictionary<string, LegacyBusinessObject> objects)
    {
        var result = new LegacyBusinessObject();
        //Loop through all the business object's fields
        foreach (var prop in typeof(LegacyBusinessObject).GetFields())
        {
            //Second loop through all the individual objects from different providers
            foreach (var ep in objects)
            {
                //Here I would need to test for all possivle value types that could 
                //be in the dictionary: <string, string>, <string, long>...
                //then cast to it and invoke the Add method like this:
                var propDictionary = prop.GetValue(result) as Dictionary<string, string>;
                propDictionary.Add(ep.Key, ep.Value);
            }
        }
        return result;
    }

现在这种方法要求我为 propDictionary 做很多笨拙的演员表。 (我也尝试构造匹配的keyvaluepair&lt;,&gt;和一个Activator来实例化它;但我找不到将其添加到另一个字典的方法)

您能想到一种更好的方法来执行此合并,它采用任意字典值类型吗?

更多背景信息:

我正在获取LegacyBusinessObject Obj1,其中包含存储在词典中的实验A和实验B的数据。不,我正在清理数据库并发现另一个LegacyBusinessObject Obj2有​​来自Lab C和Lab D的数据。事实证明摄取过程中出现了错误,而Obj1和Obj2是针对同一产品而错误地存储在两个不同的LegacyBusinessObjects。我现在想要合并数据以获得一个新的LegacyBusinessObject,其中包含来自实验室A到D的数据

1 个答案:

答案 0 :(得分:2)

很不清楚你究竟在问什么,但是:

public static LegacyBusinessObject Merge(Dictionary<string, LegacyBusinessObject> objects)
{
    var result = new LegacyBusinessObject();

    foreach (var prop in typeof(LegacyBusinessObject).GetFields())
    {
        var propDictionaryNew = (IDictionary)prop.GetValue(result);

        foreach (var dict in objects)
        {
            var propDictionaryOld = (IDictionary)prop.GetValue(dict.Value);

            foreach (DictionaryEntry de in propDictionaryOld)
            {
                propDictionaryNew[de.Key] = de.Value;

                // Or: 
                //((IDictionary)result).Add(de.Key, de.Value);
                // But be aware of exceptions if de.Key is present in multiple dictionaries
            }
        }
    }

    return result;
}

然后,测试它:

var lbo1 = new LegacyBusinessObject
{
    SomeBusinessValue1 = new Dictionary<string, string> { { "A1", "A2" }, { "B1", "B2" } },
    SomeBusinessValue2 = new Dictionary<string, long> { { "C1", 1 }, { "D1", 2 } },
    SomeBusinessValue3 = new Dictionary<string, decimal> { { "E1", 3 }, { "F1", 4 } },
};

var lbo2 = new LegacyBusinessObject
{
    SomeBusinessValue1 = new Dictionary<string, string> { { "G1", "G2" }, { "H1", "H2" } },
    SomeBusinessValue2 = new Dictionary<string, long> { { "I1", 5 }, { "J1", 6 } },
    SomeBusinessValue3 = new Dictionary<string, decimal> { { "K1", 7 }, { "L1", 8 } },
};

var result = Merge(new Dictionary<string, LegacyBusinessObject> { { "X", lbo1 }, { "Y", lbo2 } });

我在这里做了一点作弊...... Dictionary<,>实现了使用IDictionary作为IDictionary<,>之前的仿制前界面object(与a = [1,2,3] b = a print(a) print(b) b[0]=100 print(a) print(b) Output: [1, 2, 3] [1, 2, 3] [100, 2, 3] [100, 2, 3] 不同)关键和价值。通过这种方式,我不必支持不同的价值类型。使用泛型集合的反射时,一个很好的技巧是查看非泛型接口是否足以满足您的需要(因为它们更容易通过反射处理)。