我需要使用 linq 和 intersect 将多个列表合并为一个合并的不同列表。我最终得到一个空列表。知道我可能做错了什么吗?
这是我的代码:
// 合并所有不同的材质项
List<Material> combinedMaterialList = new List<Material>();
foreach (var project in projects)
{
combinedMaterialList = combinedMaterialList.Intersect(project.Materials).ToList();
}
这是 Material 类,因为相交将基于平等工作:
public int Id { get; set; }
public int ExternalId { get; set; }
public string? Name { get; set; }
public decimal Quantity { get; set; }
public bool Equals(Material m)
{
if (m is null)
{
return false;
}
// Optimization for a common success case.
if (Object.ReferenceEquals(this, m))
{
return true;
}
// If run-time types are not exactly the same, return false.
if (this.GetType() != m.GetType())
{
return false;
}
// Return true if the fields match.
// Note that the base class is not invoked because it is
// System.Object, which defines Equals as reference equality.
return (ExternalId == m.ExternalId);
}
public override int GetHashCode()
{
return HashCode.Combine(Id, ExternalId, Name, Quantity);
}
首先确保您已经为
Equals
类实现了 GetHashCode
和 Material
:
public class Material: IEquatable<Material> {
...
public bool Equals(Material other) {
if (ReferenceEquals(this, other))
return true;
if (other is null)
return false;
return ExternalId == other.ExternalId;
}
public override bool Equals(object o) => o is Material other && Equals(other);
// Note, that GetHashCode must not be more restrictive than Equals:
// If Equals compare ExternalId only, so must do GetHashCode
public override int GetHashCode() => ExternalId;
}
实施
Equals
后,您应该选择以下方法之一:
Intersect
:两个列表中的所有项目Union
:至少其中一个列表中的所有项目Except
:第一个列表中的所有项目,但不在第二个列表中
都会删除重复项。 例如:
// Since combinedMaterialList is empty,
// Intersect or Except have no meaning here: the result will be
// an empty list. The only reasonable choice is Union
List<Material> combinedMaterialList = new List<Material>();
// Combined list contains item from all project.Materials,
// duplicates removed
foreach (var project in projects) {
combinedMaterialList = combinedMaterialList
.Union(project.Materials)
.ToList();
}