我的 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 设为私有。