How to override Contains property of a list in C#?

时间:2016-07-11 21:23:52

标签: c# list override contains gethashcode

I have a list of an object List<IReportRelationMapping> that I need to check if the list does not contain a specific ReportRelationMapping object

Here is how my ReportRelationMapping looks like

public class ReportRelationMapping : IReportRelationMapping
{
     public string Name { get; set; }

     public IReportRelation LocalRelation { get; set; }

     public IReportRelation ForeignRelation { get; set; }

     public IReportRelationMapping RelatedThrough { get; set; }
}

The list contains an object if this.LocalRelation == passed.LocalRelation && this.ForeignRelation == passed.ForeignRelation or this.LocalRelation == passed.ForeignRelation && this.ForeignRelation == passed.LocalRelation

Here is what I have done in order to override the Contains property of the list

public class ReportRelationMapping : IReportRelationMapping
{
    public string Name { get; set; }

    public IReportRelation LocalRelation { get; set; }

    public IReportRelation ForeignRelation { get; set; }

    public IReportRelationMapping RelatedThrough { get; set; }

    public bool Equals(ReportRelationMapping other)
    {
        if (other == null)
        {
            return false;
        }

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

        if (this.GetType() != other.GetType())
        {
            return false;
        }

        return (this.LocalRelation == other.LocalRelation && this.ForeignRelation == other.ForeignRelation)
            || (this.LocalRelation == other.ForeignRelation && this.ForeignRelation == other.LocalRelation);
    }

    public override bool Equals(object other)
    {
        if (other == null)
        {
            return false;
        }

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

        if (this.GetType() != other.GetType())
        {
            return false;
        }

        return this.Equals(other as ReportRelationMapping);
    }

    public override int GetHashCode()
    {
        int hash = 14;
        hash = (hash * 7) + this.ForeignRelation.GetHashCode();
        return (hash * 7) + this.LocalRelation.GetHashCode();
    }

    public static bool operator ==(ReportRelationMapping lhs, ReportRelationMapping rhs)
    {
        // Check for null on left side. 
        if (Object.ReferenceEquals(lhs, null))
        {
            if (Object.ReferenceEquals(rhs, null))
            {
                // null == null = true. 
                return true;
            }

            // Only the left side is null. 
            return false;
        }
        // Equals handles case of null on right side. 
        return lhs.Equals(rhs);
    }

    public static bool operator !=(ReportRelationMapping lhs, ReportRelationMapping rhs)
    {
        return !(lhs == rhs);
    }

}

But for some reason even when the list contains a giving object I get false or "does not contains the object." When I debug my code, I can see that the the debugger reaches the Equal method so it goes through my code but it never reach GetHashCode method. I am not sure if I am implementing my GetHashCode method incorrectly here.

What did I miss here? Why Contains always return "Not Contain" in my case? How can I correctly override this Contains method of a list?

1 个答案:

答案 0 :(得分:1)

You probably should do this by calling Enumerable.Any(), like this:

bool contains = myList.Any(t =>
    (t.LocalRelation == passed.LocalRelation && t.ForeignRelation == passed.ForeignRelation)
    || (t.LocalRelation == passed.ForeignRelation && t.ForeignRelation == passed.LocalRelation)

No need to override Equals or any of that.

Or, if you don't want to use Enumerable (LINQ), there's the List.Exists method, which you call in the same way:

bool contains = myList.Exists(t =>
    (t.LocalRelation == passed.LocalRelation && t.ForeignRelation == passed.ForeignRelation)
    || (t.LocalRelation == passed.ForeignRelation && t.ForeignRelation == passed.LocalRelation)