C#通用列表联盟问题

我正在尝试使用“联盟”合并2个列表,所以我摆脱了重复。 以下是示例代码:

public class SomeDetail { public string SomeValue1 { get; set; } public string SomeValue2 { get; set; } public string SomeDate { get; set; } } public class SomeDetailComparer : IEqualityComparer { bool IEqualityComparer.Equals(SomeDetail x, SomeDetail y) { // Check whether the compared objects reference the same data. if (Object.ReferenceEquals(x, y)) return true; // Check whether any of the compared objects is null. if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) return false; return x.SomeValue1 == y.SomeValue1 && x.SomeValue2 == y.SomeValue2; } int IEqualityComparer.GetHashCode(SomeDetail obj) { return obj.SomeValue1.GetHashCode(); } } List tempList1 = new List(); List tempList2 = new List(); List detailList = tempList1.Union(tempList2, SomeDetailComparer).ToList(); 

现在问题是我可以使用Union并仍然获取具有最新日期的记录(使用SomeDate属性)。 记录本身可以在tempList1或tempList2中。

提前致谢

真正适合此目的的操作是完全外连接 。 Enumerable类具有内部Enumerable的实现,您可以使用它来查找重复项并选择您喜欢的任何内容。

 var duplicates = Enumerable.Join(tempList1, tempList2, keySelector, keySelector, (item1, item2) => (item1.SomeDate > item2.SomeDate) ? item1 : item2) .ToList(); 

keySelector只是一个函数(可以是lambda表达式),它从SomeDetail类型的对象中提取键。 现在,要实现完整的外连接,请尝试以下方法:

 var keyComparer = (SomeDetail item) => new { Value1 = item.SomeValue1, Value2 = item.SomeDetail2 }; var detailList = Enumerable.Union(tempList1.Except(tempList2, equalityComparer), tempList2.Except(tempList1, equalityComparer)).Union( Enumerable.Join(tempList1, tempList2, keyComparer, keyComparer (item1, item2) => (item1.SomeDate > item2.SomeDate) ? item1 : item2)) .ToList(); 

equalityComparer应该是一个实现IEqualityComparer的对象,并且有效地使用keyComparer函数来测试相等性。

如果能为您完成这项工作,请告诉我。

您必须能够告诉Union如何选择要使用的副本中的哪一个。 除了编写自己的联盟​​之外,我不知道如何做到这一点。

您不能使用标准的Union方法,但可以使用此特殊处理创建一个扩展方法Union for List ,并且将使用此方法,因为签名更适合。

为什么不直接使用HashSet

 List tempList1 = new List(); List tempList2 = new List(); HashSet hs = new HashSet(new SomeDetailComparer()); hs.UnionWith(tempList1); hs.UnionWith(tempList2); List detailList = hs.ToList(); 

合并通用列表

  public static List MergeListCollections(List firstList, List secondList) { List merged = new List(firstList); merged.AddRange(secondList); return merged; } 

试试这个:

 list1.RemoveAll(p => list2.Any(z => z.SomeValue1 == p.SomeValue1 && z => z.SomeValue2 == p.SomeValue1 && z => z.SomeDate == p.SomeDate)); var list3 = list2.Concat(list1).ToList();