问题在foreach循环中更新Dictionary的内容

时间:2010-07-16 09:39:14

标签: c# dictionary extension-methods

我正在为IEnumerable编写一个简单的通用更新扩展,此方法用于使用给定的键连接给定的2个业务对象或字典列表并更新特定字段。

public static void Update<TOuter, TInner, TKey>(this IEnumerable<TOuter> outer, IEnumerable<TInner> Inner, Func<TOuter, TKey> OuterKeySelector, Func<TInner, TKey> InnerKeySelector,Action<TOuter,TInner> updator)
        {
            ILookup<TKey, TInner> innerLookup = Inner.ToLookup(InnerKeySelector, element => element);

            foreach (TOuter outerItem in outer)
            {
                TKey key = OuterKeySelector(outerItem);
                if (innerLookup.Contains(key))
                {
                    foreach (TInner innerItem in innerLookup[key])
                    {
                        updator(outerItem, innerItem);
                    }
                }
            }

        }

这在普通对象中工作正常,例如:

      List<testObject> obj1 = new List<testObject>()
       {
           new testObject(){fruitId=1,name="mango"},
           new testObject(){fruitId=2,name="grapes"},
           new testObject(){fruitId=2,name="grapes"},
           new testObject(){fruitId=4,name="kivi"},
       };

       List<testObject> obj2 = new List<testObject>()
       {
           new testObject(){fruitId=2,name="apple"},
           new testObject(){fruitId=4,name="orange"},
       };

        obj1.Update(obj2,
             tx => tx.fruitId,
             ty => ty.fruitId,
            (tx,ty)=>tx.name=ty.name);

但是,我不能将这种方法用于字典,

       Dictionary<string, int> first = new Dictionary<string, int>()
       {
           {"a",1},
           {"b",2},
           {"c",9},
           {"e",5},               
       };
       Dictionary<string, int> second = new Dictionary<string, int>()
        {
           {"a",8},
           {"b",2},
           {"e",20}               
       };
       var kk = 0;

       first.Update(second,
           f1 => f1.Key,
           s1 => s1.Key,
           (f1, s1) => f1.Value = s1.Value);

它给出了以下错误

  

属性或索引器   'System.Collections.Generic.KeyValuePair.Value'   无法分配 - 它被读取   仅

我知道MSDN有一个限制

  

可以使用枚举器来阅读   集合中的数据,但他们   不能用来修改   基础集合。

是否存在以通用方式实现相同功能的黑客/解决方法?

3 个答案:

答案 0 :(得分:2)

如果您对ListDictionary的查看方式相同,那么您的代码似乎是合理的。

在您的列表示例中,您有List<MyMutableType>并且您在列表中的某个位置更新了Property MyMutableType对象。

在您的字典示例中,您有一个Dictionary<Key,MyNotMutableType>,并且您尝试用另一个MyNotMutableType实例替换某个位置的MyNotMutableType个实例,而您不是只想更改一个Property同一个对象实例。

按照用于List的方法,你应该有一个字典,如: Dictionary<Key,MyMutableType>并且在您的更新程序委托中,您应该只更新MyMutableType的属性。

希望这有帮助(抱歉我的英语不好)

答案 1 :(得分:1)

您获得的错误不是因为在枚举集合时无法修改字典,这是运行时错误。正如错误所说,KeyValuePair在Value参数上没有setter。所以f1.Value == s1.Value是不允许的。基本上KeyValuePair是不可变的,因为您无法更改值。

如果你想要这种类型的功能,我建议你创建一个更具体的更新,它特别采用字典而不是IEnumerable。

在解决字典是只读的时候,我不知道答案。

答案 2 :(得分:1)

解决这个问题的另一种方法是切换你的内心和外课。需要更新的类应该是内部的,这样就可以避免可修改的集合进入枚举..

       second.Update(first1,
           s1 => s1.Key,
           f1 => f1.Key,   
          (f1, s1) => first1[s1.Key] = f1.Value);

谢谢 andyp&amp; digEmAll