1

If I have the following methods:

public bool Equals(VehicleClaim x, VehicleClaim y)
{           
    bool isDateMatching = this.IsDateRangeMatching(x.ClaimDate, y.ClaimDate);
    // other properties use exact matching
}

private bool IsDateRangeMatching(DateTime x, DateTime y)
{       
    return x >= y.AddDays(-7) && x <= y.AddDays(7);           
}

I am comfortable overriding GetHashcode when the values exactly match but I really have no idea how to do it when a match is within a range like this.

Can anyone help please?

Niklas
  • 13,005
  • 23
  • 79
  • 119
davy
  • 4,474
  • 10
  • 48
  • 71
  • would that not give me inaccurate results? – davy Oct 03 '13 at 13:02
  • Can you clarify? Do you want VehicleClaim objects having all properties except the dates the same and the dates within 7 days range to have the same hash? – ElDog Oct 03 '13 at 13:04
  • 3
    This seems weird to me to match like this. I mean, I guess I can understand if you're locked into an API that doesn't let you provide your own equality comparer. But if you have `Date1` as Oct1, `Date2` as Oct6, `Date3` as Oct12. `Date1 == Date2`, and `Date2 == Date3`, but `Date1 != Date3`. Are you sure this is the way you want to do this? – Chris Sinclair Oct 03 '13 at 13:06
  • Thanks - I thought they had to match. This is what I'm looking for. – davy Oct 03 '13 at 13:07
  • You can't really do it. If x.Equals(x + 10) then x.GetHashCode() must equal (x+10).GetHashCode() But (x+10).Equals(x+20) so (x+10).GetHashCode() must equal (x+20).GetHashCode() You can continue to establish that all hashcodes must be equal, which rather defeats the purpose. Instead of overriding Equals in this way, maybe you could define an IsNearEnough() method instead. – urtlet Oct 03 '13 at 13:14
  • @Chris - I think so :) I've got two lists and I'm using linq's union to remove duplicates (being within 7 days of each other). I made the changes and used the test data like in your example and it seems to work so far. I will continue to test. – davy Oct 03 '13 at 13:14
  • 1
    @davy: You should consider using [this overload of `Union`](http://msdn.microsoft.com/en-us/library/bb358407.aspx) then where you can pass your own custom `IEqualityComparer`. EDIT: It just occured to me that you probably already _are_. :) Disregard me if that's the case! – Chris Sinclair Oct 03 '13 at 13:36

2 Answers2

2

I agree with Chris that

But if you have Date1 as Oct1, Date2 as Oct6, Date3 as Oct12. Date1 == Date2, and Date2 == Date3, but Date1 != Date3 is a strange behavior and the Equals purpose is not what you should use.

I don't really know if you are developping something new and if you have a database containing your vehicule claims, but I would have associated claims in the database as parent child relationship. What you have to ask yourself is: Is it possible that 2 vehicule claims within your date range can be different? Is there any other property you can use to identify a claim as unique?

Maybe you could resolve your problem this way:

Having a

List<VehicleClaim> RelatedClaims 

property in your VehicleClaim object.

Instead of Equals, use a function

bool IsRelated(VehicleClaim vehiculeClaim)
{ 
  if(all properties except date are equals)
  {  
     // since claims are sorted by date, we could compare only with the last element
     foreach(var c in RelatedClaims){ 
        if (IsDateRangeMatching(this.ClaimDate, c.ClaimDate)) 
           return true;
     }
  }

  return false;
}

and add code to construct your object

List<VehiculeClaim> yourListWithDuplicatesSortedByDate;
List<VehiculeClaim> noDuplicateList = new List<VehiculeClaim>();
foreach(var cwd in yourListWithDuplicatesSortedByDate)
{
  var relatedFound = noDuplicateList.FirstOrDefault(e => e.IsRelated(cwd));

  if (relatedFound != null)
    relatedFound.RelatedClaims.Add(cwd);
  else
    noDuplicateList.Add(cwd);
}

Problem with this, your claims must be sorted by date and it could not be the most efficient way to accomplish that.

Francis
  • 367
  • 1
  • 10
  • thanks for the effort that went into this answer. Unfortunately, it is a weird but real requirement that I have questioned. There is a point to it, which I wont bore you with. Unfortunately, I'm stuck with the DB design. – davy Oct 03 '13 at 20:21
0

Bear in mind:

If you override the GetHashCode method, you should also override Equals, and vice versa. If your overridden Equals method returns true when two objects are tested for equality, your overridden GetHashCode method must return the same value for the two objects.

http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx

Therefore it seems your GetHashCode override must return the same value for all instances, because each +- 7 day period overlaps its neighbors.

Please don't mark this as the answer. It's an answer but not the answer.

Weyland Yutani
  • 4,682
  • 1
  • 22
  • 28