C# 比较两个复杂的列表对象

C# 比较两个复杂的列表对象,c#,linq,C#,Linq,如何检查两个对象列表是否相同?我有相同结构的列表A和列表B: [XmlRoot(ElementName = "Details")] public class Details { [XmlElement(ElementName = "time")] public string time { get; set; } [XmlElement(ElementName = "duration")] public string duration { get; set; } }

如何检查两个对象列表是否相同?我有相同结构的列表A和列表B:

[XmlRoot(ElementName = "Details")]
public class Details
{
    [XmlElement(ElementName = "time")]
    public string time { get; set; }
    [XmlElement(ElementName = "duration")]
    public string duration { get; set; }
}

[XmlRoot(ElementName = "Remark")]
public class Remark
{
    [XmlElement(ElementName = "RemarkText")]
    public string RemarkText { get; set; }
    [XmlElement(ElementName = "isRemarkVisible")]
    public Boolean IsRemarkVisible { get; set; }
}

[XmlRoot(ElementName = "test")]
public class test
{
    [XmlElement(ElementName = "ID")]
    public string ID { get; set; }
    [XmlElement(ElementName = "Name")]
    public string Name { get; set; }
    public Details Details { get; set; }
    [XmlElement(ElementName = "Remark")]
    public Remark Remark { get; set; }
}

[XmlRoot(ElementName = "Tests")]
public class Tests
{
    [XmlElement(ElementName = "test")]
    public test[] test { get; set; }
}
我使用linq将其转换为列表

列表A:

Test
id=1
name=abc
details
    starttime=9.00
    endtime=12.00
    duration=1hr
Remark
    RemarkText= remark1 
    IsRemarkVisible=true
Test
id=1
name=abc
details
    starttime=9.00
    endtime=12.00
    duration=1hr
Remark
    RemarkText= remark2 
    IsRemarkVisible=true
列表B:

Test
id=1
name=abc
details
    starttime=9.00
    endtime=12.00
    duration=1hr
Remark
    RemarkText= remark1 
    IsRemarkVisible=true
Test
id=1
name=abc
details
    starttime=9.00
    endtime=12.00
    duration=1hr
Remark
    RemarkText= remark2 
    IsRemarkVisible=true
此处两个列表不相同(remarkText字段)。我想要一段代码,将比较这两个列表,并返回是否相同或否。我如何才能做到这一点

我尝试使用
List1。除了(List2)
之外,它没有比较

编辑

[XmlRoot(ElementName = "Details")]
public class Details
{
    [XmlElement(ElementName = "starttime")]
    public string starttime { get; set; }
    [XmlElement(ElementName = "endtime")]
    public string endtime { get; set; }
    [XmlElement(ElementName = "duration")]
    public string duration { get; set; }
}

[XmlRoot(ElementName = "Remark")]
public class Remark
{
    [XmlElement(ElementName = "RemarkText")]
    public string RemarkText { get; set; }
    [XmlElement(ElementName = "isRemarkVisible")]
    public Boolean IsRemarkVisible { get; set; }
}

[XmlRoot(ElementName = "test")]
public class test
{
    [XmlElement(ElementName = "ID")]
    public string ID { get; set; }
    [XmlElement(ElementName = "Name")]
    public string Name { get; set; }
    public Details Details { get; set; }
    [XmlElement(ElementName = "Remark")]
    public Remark Remark { get; set; }
    [XmlElement(ElementName = "Tags")]
    public Tags Tags { get; set; }
}

[XmlRoot(ElementName = "Tags")]
public class Tags
{
    [XmlElement(ElementName = "TagLocation")]
    public TagLocation[] TagLocation { get; set; }
}

[XmlRoot(ElementName = "TagLocation")]
public class TagLocation
{
    [XmlElement(ElementName = "Id")]
    public string Id { get; set; }
    [XmlElement(ElementName = "TagText")]
    public string TagText { get; set; }
}

[XmlRoot(ElementName = "Tests")]
public class Tests
{
    [XmlElement(ElementName = "test")]
    public test[] test { get; set; }
}
我已创建自定义IEqualityComparer:

public class Compare : IEqualityComparer<test>
{
    public bool Equals(test x, test y)
    {
        if (x == null || y == null) return false;

        bool equals = x.ID == y.ID && x.Name == y.Name && x.Remark == y.Remark
            && x.Details == y.Details;
        return equals;
    }
    public int GetHashCode(test codeh)
    {
        return (codeh.ID + codeh.Name + codeh.Remark + codeh.Details).GetHashCode();
    }
}

首先修改
test
类并实现(重写)
Equals
函数。这将使类能够将自身与另一个对象进行比较,并判断两者是否相同

理想情况下,每个类都应该有自己的
Equals
实现,父类不应该有比较子对象内部的业务。但是,考虑到您只需要比较
test
类,我们实现了
test
类本身中的所有比较逻辑

[XmlRoot(ElementName = "test")]
public class test
{
    [XmlElement(ElementName = "ID")]
    public string ID { get; set; }
    [XmlElement(ElementName = "Name")]
    public string Name { get; set; }
    public Details Details { get; set; }
    [XmlElement(ElementName = "Remark")]
    public Remark Remark { get; set; }
    [XmlElement(ElementName = "Tags")]
    public Tags Tags { get; set; }

    // override object.Equals
    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType()) return false;

        // modify the code below to suit your needs...
        test objA = (test)obj;
        if (
                this.ID != objA.ID || this.Name != objA.Name
                || this.Details.duration != objA.Details.duration || this.Details.starttime != objA.Details.starttime || this.Details.endtime != objA.Details.endtime
                || this.Remark.IsRemarkVisible != objA.Remark.IsRemarkVisible || this.Remark.RemarkText != objA.Remark.RemarkText
            ) return false;
        if (this.Tags.TagLocation.Length != objA.Tags.TagLocation.Length) return false;
        for (int i = 0; i < this.Tags.TagLocation.Length; i++)
        {
            if (this.Tags.TagLocation[i].Id != objA.Tags.TagLocation[i].Id || this.Tags.TagLocation[i].TagText != objA.Tags.TagLocation[i].TagText) return false;
        }
        return true;    // if everything matched we infer that the objects are equal.
    }

    // override object.GetHashCode
    public override int GetHashCode()
    {
        // modify the code below to generate a unique hash code for your object.
        return base.GetHashCode();
    }
}

您的问题是内部类没有相等运算符重载
==

例如,
x.Details==y.Details
始终返回
false
,无论实例保存的数据是什么,因为默认的
=
操作符只调用Equals方法,这会导致引用相等,如
object.Equals
方法中定义的那样


此外,GetHashCode方法中还有一个错误。永远不要使用字符串连接来计算哈希代码。此外,您不会重载
ToString
方法,因此它只返回相同的默认字符串,这对哈希代码计算不有用。

两个对象何时相等?通常,如果两个对象具有相同的数据,则实现一个自定义的
IEqualityComparer
,并将其传递给
。在我的示例中,如果列表B有remarkText=remark1@TimSchmelter请提供一个例子说明它是如何完成的。当然:创建一个实例并传递:
List1。除了(List2,您的比较器)
我还需要IEqualityComparer吗?不,您不需要。现在,您的类中有一个名为
Equals
的方法,您可以使用它来比较类的两个对象。我已经编辑了我的类对象,使其具有类的第三级。那会有什么不同呢?我刚刚更新了我的答案和代码示例,以满足您修改后的需求。让我知道有什么不清楚的。