我已经想到了,我如何才能在我自己的滚动解决方案来解决这个问题,但我想,如果.NET已经具备了什么,我想acheive功能 - 如果是这样,我宁愿使用一些内置.
假设我有一个的两个实例Widget对象,让我们称他们PartA和PartB.来自每个的信息来自两个不同的Web服务,但两者都具有匹配的ID.
PartA
{
ID: 19,
name: "Percy",
taste: "",
colour: "Blue",
shape: "",
same_same: "but different"
}
PartB
{
ID: 19,
name: "",
taste: "Sweet",
colour: "",
shape: "Hexagon",
same_same: "but not the same"
}
Run Code Online (Sandbox Code Playgroud)
我想合并这些来创建以下内容:
Result
{
ID: 19,
name: "Percy",
taste: "Sweet",
colour: "Blue",
shape: "Hexagon",
same_same: "but different"
}
Run Code Online (Sandbox Code Playgroud)
注意same_same每个值之间的值是如何不同的,但我们认为PartA是主节点,因此结果保留了值but different.
现在让问题复杂化:
假设我们有两个列表:
List<Widget> PartA = getPartA();
List<Widget> PartB = getPartB();
Run Code Online (Sandbox Code Playgroud)
现在这里有一些描述我想做的伪代码:
List<Widget> Result = PartA.MergeWith(PartB).MergeObjectsOn(Widget.ID).toList();
Run Code Online (Sandbox Code Playgroud)
Tim*_* S. 13
您可以编写自己的扩展方法,如下所示:
static class Extensions
{
public static IEnumerable<T> MergeWith<T>(this IEnumerable<T> source, IEnumerable<T> other) where T : ICanMerge
{
var otherItems = other.ToDictionary(x => x.Key);
foreach (var item in source)
{
yield return (T)item.MergeWith(otherItems[item.Key]);
}
}
public static string AsNullIfEmpty(this string s)
{
if (string.IsNullOrEmpty(s))
return null;
else
return s;
}
}
Run Code Online (Sandbox Code Playgroud)
在哪里ICanMerge:
public interface ICanMerge
{
object Key { get; }
ICanMerge MergeWith(ICanMerge other);
}
Run Code Online (Sandbox Code Playgroud)
实施例如:
public class Widget : ICanMerge
{
object ICanMerge.Key { get { return this.ID; } }
int ID {get;set;}
string taste {get;set;}
public ICanMerge MergeWith(ICanMerge other)
{
var merged = new Widget();
var otherWidget = (Widget)other;
merged.taste = this.taste.AsNullIfEmpty() ?? otherWidget.taste;
//...
return merged;
}
}
Run Code Online (Sandbox Code Playgroud)
然后就这么简单PartA.MergeWith(PartB).ToList().