C# 比较两个对象时有条件地更改GetHashCode()
我有两个不同的对象列表,希望根据一些属性的权重得到它们的相似性。最快的方法似乎是实现一个IEquatable接口,这就是我所做的:C# 比较两个对象时有条件地更改GetHashCode(),c#,.net,performance,comparison,gethashcode,C#,.net,Performance,Comparison,Gethashcode,我有两个不同的对象列表,希望根据一些属性的权重得到它们的相似性。最快的方法似乎是实现一个IEquatable接口,这就是我所做的: public class CompareEntry : IEquatable<CompareEntry> { public int LeadId { get; set; } public int SaleId { get; set; } public string Email { get; set; } public st
public class CompareEntry : IEquatable<CompareEntry>
{
public int LeadId { get; set; }
public int SaleId { get; set; }
public string Email { get; set; }
public string PhonePrivate { get; set; }
public string PhoneMobile { get; set; }
public string PhoneCompany { get; set; }
public string FirstName { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string CompanyName { get; set; }
public bool Equals(CompareEntry other)
{
int weight = 0;
//Check whether the compared object is null.
if (Object.ReferenceEquals(other, null))
{
return false;
}
//Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, other))
{
return true;
}
if ((this.CheckProperties(this.Email, other.Email) && this.Email == other.Email)
|| (this.CheckProperties(this.PhonePrivate, other.PhonePrivate) && this.PhonePrivate == other.PhonePrivate)
|| (this.CheckProperties(this.PhoneMobile, other.PhoneMobile) && this.PhoneMobile == other.PhoneMobile)
|| (this.CheckProperties(this.PhoneCompany, other.PhoneCompany) && this.PhoneCompany == other.PhoneCompany))
{
weight += 100;
}
if ((this.CheckProperties(this.Name, other.Name) && this.Name == other.Name)
|| (this.CheckProperties(this.FirstName, other.FirstName) && this.FirstName == other.FirstName))
{
weight += 25;
}
if ((this.CheckProperties(this.City, other.City) && this.City == other.City)
|| (this.CheckProperties(this.ZipCode, other.ZipCode) && this.ZipCode == other.ZipCode))
{
weight += 12;
}
if (this.CheckProperties(this.CompanyName, other.CompanyName) && this.CompanyName == other.CompanyName)
{
weight += 5;
}
return weight > 50;
}
public override int GetHashCode()
{
unchecked
{
int hash = (int)2166136261;
hash = hash * 16777619 ^ (string.IsNullOrEmpty(Email) ? 0 : Email.GetHashCode());
//hash = hash * 16777619 ^ (string.IsNullOrEmpty(PhonePrivate) ? 0 : PhonePrivate.GetHashCode());
//hash = hash * 16777619 ^ (string.IsNullOrEmpty(PhoneMobile) ? 0 : PhoneMobile.GetHashCode());
//hash = hash * 16777619 ^ (string.IsNullOrEmpty(PhoneCompany) ? 0 : PhoneCompany.GetHashCode());
//hash = hash * 16777619 ^ (string.IsNullOrEmpty(FirstName) ? 0 : FirstName.GetHashCode());
//hash = hash * 16777619 ^ (string.IsNullOrEmpty(Name) ? 0 : Name.GetHashCode());
//hash = hash * 16777619 ^ (string.IsNullOrEmpty(City) ? 0 : City.GetHashCode());
//hash = hash * 16777619 ^ (string.IsNullOrEmpty(ZipCode) ? 0 : ZipCode.GetHashCode());
//hash = hash * 16777619 ^ (string.IsNullOrEmpty(CompanyName) ? 0 : CompanyName.GetHashCode());
return hash;
}
}
private bool CheckProperties(string prop, string otherProp)
{
return !string.IsNullOrEmpty(prop) && !string.IsNullOrEmpty(otherProp);
}
}
公共类比较尝试:IEquatable
{
public int LeadId{get;set;}
public int SaleId{get;set;}
公共字符串电子邮件{get;set;}
公共字符串PhonePrivate{get;set;}
公共字符串PhoneMobile{get;set;}
公共字符串PhoneCompany{get;set;}
公共字符串名{get;set;}
公共字符串名称{get;set;}
公共字符串City{get;set;}
公共字符串ZipCode{get;set;}
公共字符串CompanyName{get;set;}
公共布尔等于(比较其他)
{
整数权重=0;
//检查比较对象是否为空。
if(Object.ReferenceEquals(other,null))
{
返回false;
}
//检查比较对象是否引用相同的数据。
if(Object.ReferenceEquals(this,other))
{
返回true;
}
if((this.CheckProperties(this.Email,other.Email)&&this.Email==other.Email)
||(this.CheckProperties(this.PhonePrivate,other.PhonePrivate)&&this.PhonePrivate==other.PhonePrivate)
||(this.CheckProperties(this.PhoneMobile,other.PhoneMobile)和&this.PhoneMobile==other.PhoneMobile)
||(this.CheckProperties(this.PhoneCompany,other.PhoneCompany)和&this.PhoneCompany==other.PhoneCompany))
{
重量+=100;
}
if((this.CheckProperties(this.Name,other.Name)&&this.Name==other.Name)
||(this.CheckProperties(this.FirstName,other.FirstName)&&this.FirstName==other.FirstName))
{
重量+=25;
}
if((this.CheckProperties(this.City,other.City)&&this.City==other.City)
||(this.CheckProperties(this.ZipCode,other.ZipCode)&&this.ZipCode==other.ZipCode))
{
重量+=12;
}
if(this.CheckProperties(this.CompanyName,other.CompanyName)&&this.CompanyName==other.CompanyName)
{
重量+=5;
}
返回重量>50;
}
公共覆盖int GetHashCode()
{
未经检查
{
int散列=(int)2166136261;
hash=hash*16777619^(string.IsNullOrEmpty(Email)?0:Email.GetHashCode();
//hash=hash*16777619^(string.IsNullOrEmpty(PhonePrivate)?0:PhonePrivate.GetHashCode());
//hash=hash*16777619^(string.IsNullOrEmpty(PhoneMobile)?0:PhoneMobile.GetHashCode());
//hash=hash*16777619^(string.IsNullOrEmpty(PhoneCompany)?0:PhoneCompany.GetHashCode());
//hash=hash*16777619^(string.IsNullOrEmpty(FirstName)?0:FirstName.GetHashCode();
//hash=hash*16777619^(string.IsNullOrEmpty(Name)?0:Name.GetHashCode());
//hash=hash*16777619^(string.IsNullOrEmpty(City)?0:City.GetHashCode();
//hash=hash*16777619^(string.IsNullOrEmpty(ZipCode)?0:ZipCode.GetHashCode());
//hash=hash*16777619^(string.IsNullOrEmpty(CompanyName)?0:CompanyName.GetHashCode());
返回散列;
}
}
私有bool CheckProperties(字符串属性、字符串其他属性)
{
return!string.IsNullOrEmpty(prop)和&!string.IsNullOrEmpty(otherProp);
}
}
问题是,当我重写GetHashCode()方法时,我只得到完全相同的人,或者在这种特殊情况下,只得到相同的电子邮件
如何有条件地检查GetHashCode()方法中的权重,以便使用正确的方法Equals?
或者有没有其他方法来进行相似性检查,哪种方法性能好?
Equals
/GetHashCode
不是用来比较“基本相等”的东西的。在这种情况下,相等只是一个布尔属性。特别是,使用模糊的“大致相等”方法会导致及物性问题。的文件包括以下要求:
如果(x.Equals(y)和&y.Equals(z))
返回true
,则x.Equals(z)
返回true
当你有模糊等式时,这根本不成立。仅仅因为x
与y
非常相似,y
与z
非常相似,并不意味着x
与z
非常相似
现在你可以做的是有一个只比较电话号码的相等比较器,另一个只比较姓名等的相等比较器,但这并不能真正让你模糊匹配。
Equals
/GetHashCode
不是用来比较“基本相等”的东西的。在这种情况下,相等只是一个布尔属性。特别是,使用模糊的“大致相等”方法会导致及物性问题。的文件包括以下要求:
如果(x.Equals(y)和&y.Equals(z))
返回true
,则x.Equals(z)
返回true
当你有模糊等式时,这根本不成立。仅仅因为x
与y
非常相似,y
与z
非常相似,并不意味着x
与z
非常相似
现在你可以做的是有一个只比较电话号码的相等比较器,另一个只比较姓名的相等比较器,等等-但这并不能真正让你得到模糊匹配。正确的
Equals的实现必须有这样一个属性,如果A等于B,B等于C,那么A等于C。我不确定你的Equals
实现是否有这个属性。当一个实现缺少该属性时,您通常会很难创建一个正确的GetHashCode实现