【发布时间】:2010-07-16 09:39:14
【问题描述】:
我正在为 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 有限制
枚举器可用于读取 集合中的数据,但它们 不能用于修改 基础集合。
是否有以通用方式实现相同功能的 hack/解决方法?
【问题讨论】:
-
你试过 second[f1.Key] = s1.Value 吗?
-
@andyp,它的第一个[f1.Key] = s1.Value.. 我也试过了.. 但它给出了一个错误“集合已修改;枚举操作可能无法执行。”
-
如果你真的想这样做,你可以在你的扩展中写
foreach (TOuter outerItem in outer.ToList())... -
@digEmAll,不工作。无论您做什么更改,它仍然返回键值对列表..:)
-
@Ramesh:我的意思是 andyp 解决方案(即
second[f1.Key] = s1.Value)加上我的(即扩展中的foreach修改)。我已经测试过了,它可以工作(即使不是那么优雅)
标签: c# dictionary extension-methods