如何检查两个对象列表是否相同?我有列表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
列表B:
Test
id=1
name=abc
details
starttime=9.00
endtime=12.00
duration=1hr
Remark
RemarkText= remark2
IsRemarkVisible=true
这两个列表都不相同(remarkText字段)。我想要一段代码来比较这两个列表并返回相同或不同的代码。我怎么能这样做?
我尝试使用List1.Except(List2)
,但它没有比较。
修改
我创建了自定义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();
}
}
并且
var Comparer = new Compare();
List1.Except(List2, Comparer)
这应该有用吗?
修改
[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; }
}
答案 0 :(得分:2)
首先修改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();
}
}
然后,您可以轻松地轻松比较测试类的两个对象。
e.g。
private void button1_Click(object sender, EventArgs e)
{
test test1, test2, test3;
test1 = new test { ID="1", Name ="abc"};
test1.Details = new Details { duration = "1", starttime = "9.00", endtime = "12.00" };
test1.Remark = new Remark { IsRemarkVisible = true, RemarkText = "remark1" };
test1.Tags = new Tags();
test1.Tags.TagLocation = new TagLocation[]
{
new TagLocation{ Id = "1", TagText = "tag1" },
new TagLocation{ Id = "2", TagText = "tag2" }
};
test2 = new test { ID = "1", Name = "abc" };
test2.Details = new Details { duration = "1", starttime = "9.00", endtime = "12.00" };
test2.Remark = new Remark { IsRemarkVisible = true, RemarkText = "remark2" };
test2.Tags = new Tags();
test2.Tags.TagLocation = new TagLocation[]
{
new TagLocation{ Id = "1", TagText = "tag1" },
new TagLocation{ Id = "2", TagText = "tag2" }
};
test3 = new test { ID = "1", Name = "abc" };
test3.Details = new Details { duration = "1", starttime = "9.00", endtime = "12.00" };
test3.Remark = new Remark { IsRemarkVisible = true, RemarkText = "remark2" };
test3.Tags = new Tags();
test3.Tags.TagLocation = new TagLocation[]
{
new TagLocation{ Id = "1", TagText = "tag1" },
new TagLocation{ Id = "2", TagText = "tag2" }
};
MessageBox.Show("test1.Equals(test2) ... " + test1.Equals(test2).ToString()); // shows false
MessageBox.Show("test2.Equals(test3) ... " + test2.Equals(test3).ToString()); // shows true
}
答案 1 :(得分:0)
您的问题是内部类没有相等运算符重载==
。
例如,x.Details == y.Details
始终返回false
,无论实例持有哪些数据,因为默认的==
运算符只调用Equals方法,这会导致引用相等,如在object.Equals
方法中定义。
请参阅Guidelines for Overloading Equals() and Operator == (C# Programming Guide)
此外,GetHashCode方法中存在错误。永远不要使用字符串连接来计算哈希码。此外,您不会重载ToString
方法,因此它只返回相同的默认字符串,这对于哈希码计算无用。