我的 syncfunctions hashCode 使用方法是否正确?
Is my syncfunctions hashCode usage approach correct?
请阅读我之前的问题,因为我担心在对字符串使用 hashCode 时发生冲突!
我有一个数据库 table,其中包含回购中的项目,以及一个 "incoming" 函数,其中包含模型中的项目,应该同步到数据库 table。
我使用 intersect 和 except 来实现这一点。
我用于 sunc 目的的class:
private class syncItemModel
{
public override int GetHashCode()
{
return this.ItemLookupCode.GetHashCode();
}
public override bool Equals(object other)
{
if (other is syncItemModel)
return ((syncItemModel)other).ItemLookupCode == this.ItemLookupCode;
return false;
}
public string Description { get; set; }
public string ItemLookupCode { get; set; }
public int ItemID { get; set; }
}
然后我在我的方法中使用这个:
1) 将数据table 项转换为同步模型:
var DbItemsInCampaignDiscount_SyncModel =
DbItemsInCampaignDiscount(dbcampaignDiscount, datacontext)
.Select(i => new syncItemModel { Description = i.Description,
ItemLookupCode = i.ItemLookupCode,
ItemID = i.ID}).ToList();
2) 将我的传入项目模型转换为同步模型:
var ItemsInCampaignDiscountModel_SyncModel = modelItems
.Select(i => new syncItemModel { Description =
i.Description, ItemLookupCode = i.ItemLookUpCode, ItemID =0 }).ToList();
3) 相交:
var CommonItemInDbAndModel =
ItemsInCampaignDiscountModel_SyncModel.Intersect(DbItemsInCampaignDiscount_SyncModel).ToList();
4) 取出数据库中要删除的项目(传入模型项目中不存在的项目)
var SyncModel_OnlyInDb =
DbItemsInCampaignDiscount_SyncModel.Except(CommonItemInDbAndModel).ToList();
5) 取出要添加到数据库中的项,传入模型中存在但db中不存在的项:
var SyncModel_OnlyInModel =
ItemsInCampaignDiscountModel_SyncModel.Except(CommonItemInDbAndModel).ToList();
那么我的问题是——会不会是碰撞?我示例中的两个不同的 ItemLookupCode 是否可以视为相同的 ItemLookupCode?因为相交并且除了使用 HashCode !或者使用 Equal 函数 "double check" - 所以这种方法可以安全使用?如果它有可能发生碰撞,那么这个机会有多大?
是的,哈希冲突总是存在的,这就是为什么应该通过调用 Equals()
来确认身份。必须实施 GetHashCode() 和 Equals() correctly.
LINQ to Objects internally 中的 Except()
使用 HashSet
,如果发生散列冲突,它将调用 Equals 来保证身份。当您使用单个 属性 时,您可以很好地代理对其哈希码和 equals 方法的调用。
请在下面找到一些关于您的实施的评论:
比较==
用== 比较字符串没问题,但如果将类型更改为非基本类型,则会出现问题,因为将比较对象引用而不是内容。代理调用 Equals()
而不是 ==
.
对象的可变性
即 very error prone 将 gethashcode/Equals 逻辑绑定到可变状态。我强烈建议封装你的状态,这样一旦你创建了你的对象,它就无法更改,为了安全起见,将 set
设为私有。
请阅读我之前的问题,因为我担心在对字符串使用 hashCode 时发生冲突!
我有一个数据库 table,其中包含回购中的项目,以及一个 "incoming" 函数,其中包含模型中的项目,应该同步到数据库 table。
我使用 intersect 和 except 来实现这一点。
我用于 sunc 目的的class:
private class syncItemModel
{
public override int GetHashCode()
{
return this.ItemLookupCode.GetHashCode();
}
public override bool Equals(object other)
{
if (other is syncItemModel)
return ((syncItemModel)other).ItemLookupCode == this.ItemLookupCode;
return false;
}
public string Description { get; set; }
public string ItemLookupCode { get; set; }
public int ItemID { get; set; }
}
然后我在我的方法中使用这个: 1) 将数据table 项转换为同步模型:
var DbItemsInCampaignDiscount_SyncModel =
DbItemsInCampaignDiscount(dbcampaignDiscount, datacontext)
.Select(i => new syncItemModel { Description = i.Description,
ItemLookupCode = i.ItemLookupCode,
ItemID = i.ID}).ToList();
2) 将我的传入项目模型转换为同步模型:
var ItemsInCampaignDiscountModel_SyncModel = modelItems
.Select(i => new syncItemModel { Description =
i.Description, ItemLookupCode = i.ItemLookUpCode, ItemID =0 }).ToList();
3) 相交:
var CommonItemInDbAndModel =
ItemsInCampaignDiscountModel_SyncModel.Intersect(DbItemsInCampaignDiscount_SyncModel).ToList();
4) 取出数据库中要删除的项目(传入模型项目中不存在的项目)
var SyncModel_OnlyInDb =
DbItemsInCampaignDiscount_SyncModel.Except(CommonItemInDbAndModel).ToList();
5) 取出要添加到数据库中的项,传入模型中存在但db中不存在的项:
var SyncModel_OnlyInModel =
ItemsInCampaignDiscountModel_SyncModel.Except(CommonItemInDbAndModel).ToList();
那么我的问题是——会不会是碰撞?我示例中的两个不同的 ItemLookupCode 是否可以视为相同的 ItemLookupCode?因为相交并且除了使用 HashCode !或者使用 Equal 函数 "double check" - 所以这种方法可以安全使用?如果它有可能发生碰撞,那么这个机会有多大?
是的,哈希冲突总是存在的,这就是为什么应该通过调用 Equals()
来确认身份。必须实施 GetHashCode() 和 Equals() correctly.
Except()
使用 HashSet
,如果发生散列冲突,它将调用 Equals 来保证身份。当您使用单个 属性 时,您可以很好地代理对其哈希码和 equals 方法的调用。
请在下面找到一些关于您的实施的评论:
比较==
用== 比较字符串没问题,但如果将类型更改为非基本类型,则会出现问题,因为将比较对象引用而不是内容。代理调用 Equals()
而不是 ==
.
对象的可变性
即 very error prone 将 gethashcode/Equals 逻辑绑定到可变状态。我强烈建议封装你的状态,这样一旦你创建了你的对象,它就无法更改,为了安全起见,将 set
设为私有。