如何使用不同的相等性检查实现IEquatable

我有一个 MyCustomSet 类,实现了 IEquatable ,如下所示。

当我要检查所有三个集合(Seta *,SetB *和SetC *)的相等性时,这效果很好。但要求表明,我还需要仅检查Seta *,SetB *或SetC *或其组合(Seta *和SetB *,Seta *和SetC *或SetB *和SetC *)的相等性并忽略检查的能力与检查中不需要的任何其他Set相等。

当前,我正在使用 foreach 和LINQ遍历Sets以执行部分​​相等性检查,这种方法行之有效,但对于以下情况似乎不太有效大型数据集。

也许答案是直面我,但我看不到,因为我不知道如何实现可以处理的 IEquatable 不同的相等性检查。

有人会协助我提供一些建议或指导,以指导如何实施吗?一个例子将更加令人赞赏。

public static class HashCode
{
    public const int Start = 17;

    public static int Hash<T>(this int hash,T obj)
    {
        var h = EqualityComparer<T>.Default.GetHashCode(obj);
        return unchecked((hash * 439) + h);
    }
}

public class MyCustomSetModel
{
    public sealed class MyCustomSet : IEquatable<MyCustomSet>
    {
        public string ItemName { get; set; }
        public string ItemType { get; set; }

        public double Seta1 { get; set; }
        public double Seta2 { get; set; }
        public double Seta3 { get; set; }

        public double SetB1 { get; set; }
        public double SetB2 { get; set; }
        public double SetB3 { get; set; }

        public double SetC1 { get; set; }
        public double SetC2 { get; set; }
        public double SetC3 { get; set; }

        public bool Equals(MyCustomSet other)
        {
            if (ReferenceEquals(other,null))
            {
                return false;
            }

            if (ReferenceEquals(other,this))
            {
                return true;
            }

            return
                (
                (this.ItemName == other.ItemName) &&
                (this.ItemType == other.ItemType) &&

                (this.Seta1 == other.Seta1) &&
                (this.Seta2 == other.Seta2) &&
                (this.Seta3 == other.Seta3) &&

                (this.SetB1 == other.SetB1) &&
                (this.SetB2 == other.SetB2) &&
                (this.SetB3 == other.SetB3) &&

                (this.SetC1 == other.SetC1) &&
                (this.SetC2 == other.SetC2) &&
                (this.SetC3 == other.SetC3)
                );
        }

        public override bool Equals(object obj) => Equals(obj as MyCustomSet);

        public override int GetHashCode()
        {
            unchecked
            {
                return HashCode.Start
                    .Hash(ItemName)
                    .Hash(ItemType)

                    .Hash(Seta1)
                    .Hash(Seta2)
                    .Hash(Seta3)

                    .Hash(SetB1)
                    .Hash(SetB2)
                    .Hash(SetB3)

                    .Hash(SetC1)
                    .Hash(SetC2)
                    .Hash(SetC3);
            }
        }
    }
}

*更新:*

感谢Matthew Watson向我指出了正确的方向。因此,我实现了一个自定义比较器,如下所示。看起来它正在运行,但是如果有人发现潜在的问题或有更好的实施空间,请随时发表评论。

        public sealed class MyCustomSetComparer : IEqualityComparer<MyCustomSet>
        {
            private bool _compareSeta;
            private bool _compareSetB;
            private bool _compareSetC;

            public MyCustomSetComparer(bool compareSeta = true,bool compareSetB = true,bool compareSetC = true)
            {
                _compareSeta = compareSeta;
                _compareSetB = compareSetB;
                _compareSetC = compareSetC;
            }

            public bool Equals(MyCustomSet x,MyCustomSet y)
            {
                if (Object.ReferenceEquals(x,y))
                {
                    return true;
                }

                if (Object.ReferenceEquals(x,null) || Object.ReferenceEquals(y,null))
                {
                    return false;
                }

                bool result =
                    (x.ItemName == y.ItemName) &&
                    (x.ItemType == y.ItemType);

                if (_compareSeta)
                {
                    result = result &&
                        (x.Seta1 == y.Seta1) &&
                        (x.Seta2 == y.Seta2) &&
                        (x.Seta3 == y.Seta3);
                }

                if (_compareSetB)
                {
                    result = result &&
                        (x.SetB1 == y.SetB1) &&
                        (x.SetB2 == y.SetB2) &&
                        (x.SetB3 == y.SetB3);
                }

                if (_compareSetC)
                {
                    result = result &&
                        (x.SetC1 == y.SetC1) &&
                        (x.SetC2 == y.SetC2) &&
                        (x.SetC3 == y.SetC3);
                }

                return result;
            }

            public int GetHashCode(MyCustomSet item)
            {
                if (Object.ReferenceEquals(item,null))
                {
                    return 0;
                }

                int hash = HashCode.Start
                    .Hash(item.ItemName)
                    .Hash(item.ItemType);

                if (_compareSeta)
                {
                    hash = hash.Hash(item.Seta1)
                        .Hash(item.Seta2)
                        .Hash(item.Seta3);
                }

                if (_compareSetB)
                {
                    hash = hash.Hash(item.SetB1)
                        .Hash(item.SetB2)
                        .Hash(item.SetB3);
                }

                if (_compareSetC)
                {
                    hash = hash.Hash(item.SetC1)
                        .Hash(item.SetC2)
                        .Hash(item.SetC3);
                }

                unchecked
                {
                    return hash;
                }
            }
        }
xiazai1999 回答:如何使用不同的相等性检查实现IEquatable

根据Matthew Watson的评论,这是使用IEqualityComparer<T>而不是IEquatable<T>的绝佳时机。我建议仅在对类型的相等性有一个显而易见的自然定义时,才实施IEquatable<T>。如果存在多个平等选项,并且没有一个选项比其他选项更合理,请实施IEqualityComparer<T>-以几种不同的实现类型或以创建方式为参数的单个实现类型。

本文链接:https://www.f2er.com/2657562.html

大家都在问