簡體   English   中英

linq&distinct,實現equals和gethashcode

[英]linq & distinct, implementing the equals & gethashcode

所以我正在努力使這項工作,我似乎無法知道為什么它不起作用

演示代碼;

namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        var myVar = new List<parent >();
        myVar.Add(new parent() { id = "id1", blah1 = "blah1", c1 = new child() { blah2 = "blah2", blah3 = "blah3" } });
        myVar.Add(new parent() { id = "id1", blah1 = "blah1", c1 = new child() { blah2 = "blah2", blah3 = "blah3" } });

        var test = myVar.Distinct();

        Console.ReadKey();

    }
}


public class parent : IEquatable<parent>
{
    public String id { get;set;}
    public String blah1 { get; set; }
    public child c1 { get; set; }

    public override int GetHashCode()
    {
        unchecked // Overflow is fine, just wrap
        {
            int hash = 17;
            // Suitable nullity checks etc, of course :)
            hash = hash * 23 + id.GetHashCode();
            hash = hash * 23 + blah1.GetHashCode();
            hash = hash * 23 + (c1 == null ? 0 : c1.GetHashCode());
            return hash;
        }
    }

    public bool Equals(parent other)
    {
        return object.Equals(id, other.id) &&
            object.Equals(blah1, other.blah1) &&
            object.Equals(c1, other.c1);
    }

}

public class child : IEquatable<child>
{
    public String blah2 { get; set; }
    public String blah3 { get; set; }

    public override int GetHashCode()
    {
        unchecked // Overflow is fine, just wrap
        {
            int hash = 17;
            // Suitable nullity checks etc, of course :)
            hash = hash * 23 + blah2.GetHashCode();
            hash = hash * 23 + blah3.GetHashCode();
            return hash;
        }
    }

    public bool Equals(child other)
    {
        return object.Equals(blah2, other.blah2) &&
            object.Equals(blah3, other.blah3);
    }

}
}

任何人都可以發現我的錯誤?

您需要覆蓋Equals(object)方法:

public override bool Equals(object obj) {
    return Equals(obj as parent);
}

object.Equals方法(與EqualityComparer<T>.Default )不使用IEquatable接口。 因此,當您編寫object.Equals(c1, other.c1) ,它不會調用您的Child.Equals(Child)方法。

parent也不一定非常需要這樣做,但你真的應該這樣做。

您可以執行SLaks建議的操作,也可以在parent類中使用EqualityComparer<child>.Default來使用IEquatable<child>實現:

  public bool Equals(parent other)
  {
   return object.Equals(id, other.id) &&
    object.Equals(blah1, other.blah1) &&
    EqualityComparer<child>.Default.Equals(c1, other.c1);
 }

在添加計算哈希時,您可能想要嘗試類似的東西

hash ^= id.GetHashCode();

不確定這是否是導致您的問題的原因。

這里有幾件事要做。 如果我要在GetHashCodeIEquatable ==或IEquatable等類中實現相等的任何方面,我總是使用以下模式。

  1. 覆蓋等於
  2. 覆蓋GetHashCode
  3. 實現IEquatable<T> ,這意味着實現Equals(T)
  4. 實施!=
  5. 實施==

所以,如果我有一個名為ExpiryMonth的類具有屬性Year和Month,那么這就是該實現的外觀。 現在適應其他類型的課程是一項相當盲目的任務。

我已將此模式基於其他幾個stackoverflow答案,這些答案都值得贊揚,但我一直沒有跟蹤。

通過始終將所有這些元素一起實現,它確保在各種上下文中進行適當的相等操作,包括字典和Linq操作。

    public static bool operator !=(ExpiryMonth em1, ExpiryMonth em2)
    {
        if (((object)em1) == null || ((object)em2) == null)
        {
            return !Object.Equals(em1, em2);
        }
        else
        {
            return !(em1.Equals(em2));
        }
    }
    public static bool operator ==(ExpiryMonth em1, ExpiryMonth em2)
    {
        if (((object)em1) == null || ((object)em2) == null)
        {
            return Object.Equals(em1, em2);
        }
        else
        {
            return em1.Equals(em2);
        }
    }
    public bool Equals(ExpiryMonth other)
    {
        if (other == null) { return false; }
        return Year == other.Year && Month == other.Month;
    }
    public override bool Equals(object obj)
    {
        if (obj == null) { return false; }
        ExpiryMonth em = obj as ExpiryMonth;
        if (em == null) { return false; }
        else { return Equals(em); }
    }
    public override int GetHashCode()
    {
        unchecked // Overflow is not a problem
        {
            var result = 17;
            result = (result * 397) + Year.GetHashCode();
            result = (result * 397) + Month.GetHashCode();
            return result;
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM