linq C# -交叉两个不同的自定义列表

j0pj023g  于 2023-09-28  发布在  C#
关注(0)|答案(2)|浏览(133)

我有两个不同的对象列表,我想相交,所以我为我的不同的自定义对象创建了一个 Package 器对象,在那里我存储了一个比较变量并实现了IEquatable,这样我就可以运行LINQ相交函数。
由于某种原因,我不能得到我想要的结果,只是给我null返回。在equals函数中也没有碰到断点。有人知道我哪里做错了吗?可能是简单的事。

internal class CompareObject : IEquatable<CompareObject>
{
    public CompareObject(customClass myParentObject) 
    {
        this.myParentObject = myParentObject;
        this.compareString = myParentObject.customCompareField;
    }
    public string compareString { get; set; }
    public object myParentObject { get; set; }

    public bool Equals(CompareObject? other)
    {
        return this.compareString == other.compareString;
    }
}
internal class CompareObjectA : CompareObject
{
    public CompareObjectA(customClassA myParentObject)
    {
        this.myParentObject = myParentObject;
        this.compareString = myParentObject.customCompareField;
    }
}
internal class CompareObjectB : CompareObject
{
    public CompareObjectB(customClassB myParentObject)
    {
        this.myParentObject = myParentObject;
        this.compareString = myParentObject.customCompareField;
    }
}
public void Execute()
    {
        var listA = new List<CompareObjectA>(<<SAMPLE VALUES>>);
        var listB = new List<CompareObjectB>(<<SAMPLE VALUES>>);

        var listC = listA.Select(a => (CompareObject)a).Intersect(listB.Select(a => ((CompareObject)a));
    }
k10s72fa

k10s72fa1#

最简单的方法就是这样写:

var result = a.IntersectBy(b, x => x.compareString);
xzlaal3s

xzlaal3s2#

Enumerable.Intersect是一个基于集合的方法,它不是线性搜索,所以它不仅仅使用Equals来比较两个对象。相反,它使用第一个GetHashCode。一般来说,你应该总是同时覆盖EqualsGetHashCode,如果你实现了IEquatable<T>也是如此;

public override bool Equals(object? obj)
{
    return obj is CompareObject obj2 && this.Equals(obj2);
}

public bool Equals(CompareObject? other)
{
    return this.compareString == other?.compareString;
}

public override int GetHashCode()
{
    return compareString.GetHashCode();
}

请注意,您必须以这种方式使用Intersect

var listC = listA.Intersect(listB).ToList();

为类提供自定义比较器的另一种方法是实现IEqualityComparer<T>,这需要实现EqualsGetHashCode

public class CompareStringComparer : IEqualityComparer<CompareObject>
{
    public bool Equals(CompareObject x, CompareObject y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (ReferenceEquals(x, null)) return false;
        if (ReferenceEquals(y, null)) return false;
        return x.compareString == y.compareString;
    }

    public int GetHashCode(CompareObject obj)
    {
        return obj.compareString.GetHashCode();
    }
}

您可以将此比较器用于许多LINQ方法,也可以用于Intersect

var listC = listA.Intersect(listB, new CompareStringComparer()).ToList();

如果您有多种方法来比较对象,或者如果您不能或不想修改类本身,则可以使用这种方法。

相关问题