C# 比较两个对象的字典

C# 比较两个对象的字典,c#,asp.net,dictionary,C#,Asp.net,Dictionary,假设我有这些东西 var address = new Address("5455 Apache Trail", "Queen Creek", "AZ", "85243"); var person = new Person("Jane", "Smith", address); 我想用字典检查这些对象的相等性,所以是这样的 var dictionary = new Dictionary<object>{ [address] = address, [person]

假设我有这些东西

    var address = new Address("5455 Apache Trail", "Queen Creek", "AZ", "85243");
    var person = new Person("Jane", "Smith", address);
我想用字典检查这些对象的相等性,所以是这样的

    var dictionary = new Dictionary<object>{ [address] = address, [person] = person};
    Assert.IsTrue(dictionary.ContainsKey(new Address("5455 Apache Trail", "Queen Creek", "AZ", "85243")));
    Assert.IsTrue(dictionary.ContainsKey(new Person("Jane", "Smith", address)));

因为您创建了地址和人员的新引用,它与键不匹配,所以以下断言语句可以工作:

 var dictionary = new Dictionary<object, object> { [address] = address, [person] = person };
 Assert.IsTrue(dictionary.ContainsKey(address));
 Assert.IsTrue(dictionary.ContainsKey(person));
var dictionary=newdictionary{[address]=address,[person]=person};
Assert.IsTrue(dictionary.ContainsKey(address));
Assert.IsTrue(dictionary.ContainsKey(person));
更新

如果需要创建新引用,请使用字典的EqualityComparer参数:

public class CustomEqualityComparer : IEqualityComparer<object>
{
    public new bool Equals(object x, object y)
    {
        if (x is Address && y is Address)
        {
            var xAddress = x as Address;
            var yAddress = y as Address;
            return xAddress.Line1 == yAddress.Line1 &&
               xAddress.Line2 == yAddress.Line2 &&
               xAddress.Line3 == yAddress.Line3 &&
               xAddress.Line4 == yAddress.Line4;
        }

        if (x is Person && y is Person)
        {
            var xPerson = x as Person;
            var yPerson = y as Person;
            return xPerson.FirstName == yPerson.FirstName &&
               xPerson.LastName == yPerson.LastName;
        }

        return false;
    }

    public int GetHashCode(object obj)
    {
        if (obj is Address)
        {
            var address = obj as Address;
            return  address.Line1.GetHashCode() ^
                    address.Line2.GetHashCode() ^
                    address.Line3.GetHashCode() ^
                    address.Line4.GetHashCode();
        }

        if (obj is Person)
        {
            var person = obj as Person;
            return person.FirstName.GetHashCode() ^
                   person.LastName.GetHashCode();
        }

        return obj.GetHashCode();
    }
}
公共类CustomEqualityComparer:IEqualityComparer
{
公共新布尔等于(对象x、对象y)
{
if(x是地址&&y是地址)
{
var xAddress=x作为地址;
var yAddress=y作为地址;
返回xAddress.Line1==yAddress.Line1&&
xAddress.Line2==yAddress.Line2&&
xAddress.Line3==yAddress.Line3&&
xAddress.Line4==yAddress.Line4;
}
如果(x为个人&&y为个人)
{
var xPerson=x作为个人;
var yPerson=y作为个人;
返回xPerson.FirstName==yPerson.FirstName&&
xPerson.LastName==yPerson.LastName;
}
返回false;
}
public int GetHashCode(对象obj)
{
if(obj是地址)
{
var地址=obj作为地址;
返回地址.Line1.GetHashCode()^
address.Line2.GetHashCode()^
address.Line3.GetHashCode()^
address.Line4.GetHashCode();
}
如果(obj是个人)
{
var person=obj as person;
return person.FirstName.GetHashCode()^
person.LastName.GetHashCode();
}
返回obj.GetHashCode();
}
}
然后在你的测试中:

var dictionary = new Dictionary<object, object>(new CustomEqualityComparer())
        { [address] = address, [person] = person };
        Assert.IsTrue(dictionary.ContainsKey(new Address("5455 Apache Trail", "Queen Creek", "AZ", "85243")));
        Assert.IsTrue(dictionary.ContainsKey(person));
var dictionary=newdictionary(new CustomEqualityComparer())
{[地址]=地址,[人]=人};
Assert.IsTrue(dictionary.ContainsKey(新地址(“5455 Apache Trail”、“Queen Creek”、“AZ”、“85243”));
Assert.IsTrue(dictionary.ContainsKey(person));

建议使用泛型类型,而不要使用字典中的对象;考虑将密钥从对象更改为类型。

< p>因为创建地址和人的新引用,它与密钥不匹配,下面的断言语句将工作:

 var dictionary = new Dictionary<object, object> { [address] = address, [person] = person };
 Assert.IsTrue(dictionary.ContainsKey(address));
 Assert.IsTrue(dictionary.ContainsKey(person));
var dictionary=newdictionary{[address]=address,[person]=person};
Assert.IsTrue(dictionary.ContainsKey(address));
Assert.IsTrue(dictionary.ContainsKey(person));
更新

如果需要创建新引用,请使用字典的EqualityComparer参数:

public class CustomEqualityComparer : IEqualityComparer<object>
{
    public new bool Equals(object x, object y)
    {
        if (x is Address && y is Address)
        {
            var xAddress = x as Address;
            var yAddress = y as Address;
            return xAddress.Line1 == yAddress.Line1 &&
               xAddress.Line2 == yAddress.Line2 &&
               xAddress.Line3 == yAddress.Line3 &&
               xAddress.Line4 == yAddress.Line4;
        }

        if (x is Person && y is Person)
        {
            var xPerson = x as Person;
            var yPerson = y as Person;
            return xPerson.FirstName == yPerson.FirstName &&
               xPerson.LastName == yPerson.LastName;
        }

        return false;
    }

    public int GetHashCode(object obj)
    {
        if (obj is Address)
        {
            var address = obj as Address;
            return  address.Line1.GetHashCode() ^
                    address.Line2.GetHashCode() ^
                    address.Line3.GetHashCode() ^
                    address.Line4.GetHashCode();
        }

        if (obj is Person)
        {
            var person = obj as Person;
            return person.FirstName.GetHashCode() ^
                   person.LastName.GetHashCode();
        }

        return obj.GetHashCode();
    }
}
公共类CustomEqualityComparer:IEqualityComparer
{
公共新布尔等于(对象x、对象y)
{
if(x是地址&&y是地址)
{
var xAddress=x作为地址;
var yAddress=y作为地址;
返回xAddress.Line1==yAddress.Line1&&
xAddress.Line2==yAddress.Line2&&
xAddress.Line3==yAddress.Line3&&
xAddress.Line4==yAddress.Line4;
}
如果(x为个人&&y为个人)
{
var xPerson=x作为个人;
var yPerson=y作为个人;
返回xPerson.FirstName==yPerson.FirstName&&
xPerson.LastName==yPerson.LastName;
}
返回false;
}
public int GetHashCode(对象obj)
{
if(obj是地址)
{
var地址=obj作为地址;
返回地址.Line1.GetHashCode()^
address.Line2.GetHashCode()^
address.Line3.GetHashCode()^
address.Line4.GetHashCode();
}
如果(obj是个人)
{
var person=obj as person;
return person.FirstName.GetHashCode()^
person.LastName.GetHashCode();
}
返回obj.GetHashCode();
}
}
然后在你的测试中:

var dictionary = new Dictionary<object, object>(new CustomEqualityComparer())
        { [address] = address, [person] = person };
        Assert.IsTrue(dictionary.ContainsKey(new Address("5455 Apache Trail", "Queen Creek", "AZ", "85243")));
        Assert.IsTrue(dictionary.ContainsKey(person));
var dictionary=newdictionary(new CustomEqualityComparer())
{[地址]=地址,[人]=人};
Assert.IsTrue(dictionary.ContainsKey(新地址(“5455 Apache Trail”、“Queen Creek”、“AZ”、“85243”));
Assert.IsTrue(dictionary.ContainsKey(person));

建议使用泛型类型,而不要使用字典中的对象;考虑将密钥从对象更改为类型。

您需要传递一个适当的实例。 如果未传递任何比较器,则字典将使用默认比较器。(). 仅当传递的参数与对象的实例相同时,才会返回true。您必须创建自己的比较器

或者,您可以覆盖要存储在字典中的所有类中的GetHashCode和Equals。然后EqualityComparer.Default调用GetHashCodeEquals的相应覆盖,您就可以设置了。如果要重写这两个函数,则不需要创建比较器或将比较器传递给字典

基于OP的编辑进行编辑:

请注意,GetHashCode的实现应该与Equals的实现一致:

a.Equals(b)=>b.Equals(a)=>a.GetHashCode()==b.GetHashCode()

在您的情况下,由于您仍在使用对象默认的GetHashCode,因此上述条件不适用

GetHashCode的实现方式如下:

  public override int GetHashCode(){
        return this.FirstName.GetHashCode() ^ 
               this.LastName.GetHashCode() ^ 
               this.Address.GetHashCode(); 
    }

您需要传递一个适当的实例。 如果未传递任何比较器,则字典将使用默认比较器。(). 仅当传递的参数与对象的实例相同时,才会返回true。您必须创建自己的比较器

或者可以重写GetHashCode和Equals