根据这篇文章中所有的答案,这里是我能想到的最通用的解决方案。
我创建了两个版本的IDictionary.Merge()扩展:
<T, U>(sourceLeft, sourceRight)
<T, U>(sourceLeft, sourceRight, Func<U, U, U> mergeExpression)
其中第二个是第一个的修改版本,允许你指定一个lambda表达式来处理像这样的重复:
Dictionary<string, object> customAttributes =
HtmlHelper
.AnonymousObjectToHtmlAttributes(htmlAttributes)
.ToDictionary(
ca => ca.Key,
ca => ca.Value
);
Dictionary<string, object> fixedAttributes =
new RouteValueDictionary(
new {
@class = "form-control"
}).ToDictionary(
fa => fa.Key,
fa => fa.Value
);
//appending the html class attributes
IDictionary<string, object> editorAttributes = fixedAttributes.Merge(customAttributes, (leftValue, rightValue) => leftValue + " " + rightValue);
(您可以关注ToDictionary()和Merge()部分)
下面是扩展类(右边有两个版本的扩展,接受一个IDictionary的集合):
public static class IDictionaryExtension
{
public static IDictionary<T, U> Merge<T, U>(this IDictionary<T, U> sourceLeft, IDictionary<T, U> sourceRight)
{
IDictionary<T, U> result = new Dictionary<T,U>();
sourceLeft
.Concat(sourceRight)
.ToList()
.ForEach(kvp =>
result[kvp.Key] = kvp.Value
);
return result;
}
public static IDictionary<T, U> Merge<T, U>(this IDictionary<T, U> sourceLeft, IDictionary<T, U> sourceRight, Func<U, U, U> mergeExpression)
{
IDictionary<T, U> result = new Dictionary<T,U>();
//Merge expression example
//(leftValue, rightValue) => leftValue + " " + rightValue;
sourceLeft
.Concat(sourceRight)
.ToList()
.ForEach(kvp =>
result[kvp.Key] =
(!result.ContainsKey(kvp.Key))
? kvp.Value
: mergeExpression(result[kvp.Key], kvp.Value)
);
return result;
}
public static IDictionary<T, U> Merge<T, U>(this IDictionary<T, U> sourceLeft, IEnumerable<IDictionary<T, U>> sourcesRight)
{
IDictionary<T, U> result = new Dictionary<T, U>();
new[] { sourceLeft }
.Concat(sourcesRight)
.ToList()
.ForEach(dic =>
result = result.Merge(dic)
);
return result;
}
public static IDictionary<T, U> Merge<T, U>(this IDictionary<T, U> sourceLeft, IEnumerable<IDictionary<T, U>> sourcesRight, Func<U, U, U> mergeExpression)
{
IDictionary<T, U> result = new Dictionary<T, U>();
new[] { sourceLeft }
.Concat(sourcesRight)
.ToList()
.ForEach(dic =>
result = result.Merge(dic, mergeExpression)
);
return result;
}
}
mergeExpression让您轻松地处理您想合并项目的方式,如加法,除法,乘法或任何您想要的特定过程。
请注意,我还没有测试扩展的集合版本…它们可能仍然需要一些调整。
此外,扩展不修改原来的字典,你必须分配回来,如果你想。