【问题标题】:C# equality with list-based properties具有基于列表的属性的 C# 相等性
【发布时间】:2019-01-22 13:41:54
【问题描述】:

我已经阅读了许多与 C# 中的正确相等性相关的文章:

http://www.loganfranken.com/blog/687/overriding-equals-in-c-part-1/

What is the best algorithm for an overridden System.Object.GetHashCode?

假设以下示例类:

public class CustomData
{
    public string Name { get; set;}

    public IList<double> Values = new List<double>();
}

是否仍然可以使用 .Equals() 比较 Values 属性?这是我的意思的完整平等示例:

#region Equality

    public override bool Equals(object value)
    {
        if(Object.ReferenceEquals(null, value)) return false;   // Is null?
        if (Object.ReferenceEquals(this, value)) return true;   // Is the same object?
        if (value.GetType() != this.GetType()) return false;    // Is the same type?

        return IsEqual((CustomData)value);
    }

    public bool Equals(CustomData obj)
    {
        if (Object.ReferenceEquals(null, obj)) return false;    // Is null?
        if (Object.ReferenceEquals(this, obj)) return true;     // Is the same object?

        return IsEqual(obj);
    }

    private bool IsEqual(CustomData obj)
    {
        return obj is CustomData other
            && other.Name.Equals(Name)
            && other.Values.Equals(Values);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            // Choose large primes to avoid hashing collisions
            const int HashingBase = (int) 2166136261;
            const int HashingMultiplier = 16777619;

            int hash = HashingBase;
            hash = (hash * HashingMultiplier) ^ (!Object.ReferenceEquals(null, Name) ? Name.GetHashCode() : 0);
            hash = (hash * HashingMultiplier) ^ (!Object.ReferenceEquals(null, Values) ? Values.GetHashCode() : 0);
            return hash;
        }
    }

    public static bool operator ==(CustomData obj, CustomData other)
    {
        if (Object.ReferenceEquals(obj, other)) return true;
        if (Object.ReferenceEquals(null, obj)) return false;    // Ensure that "obj" isn't null

        return (obj.Equals(other));
    }

    public static bool operator !=(CustomData obj, CustomData other) => !(obj == other);

#endregion

【问题讨论】:

  • 我认为other.Values.Equals(Values); 应该是other.Values.SequenceEqual(Values);
  • 是的,这就是我对 ???? 所做的更改

标签: c# .net


【解决方案1】:

List&lt;T&gt;.Equals(List&lt;T&gt; other) 将比较引用。如果要将属性Values 的相等性定义为doubles 的相同序列,请使用IEnumerable&lt;TSource&gt;.SequenceEqual.(IEnemerable&lt;TSource&gt; other) 方法(MSDN)。请参阅下面的 IsEqual(CustomData obj) 的重构版本:

private bool IsEqual(CustomData obj)
{
    return obj is CustomData other
        && other.Name.Equals(Name)
        && other.Values.SequenceEqual(Values);
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 2011-06-07
    相关资源
    最近更新 更多