I want to use a date range (from one date to another date) as a key for a dictionary, so I wrote my own struct:
struct DateRange
{
public DateTime St
In C# 7
you can do this:
public override int GetHashCode() => (Start, End).GetHashCode();
The ValueTuple
is available in .NET Framework 4.7
and .NET Core
, or via NuGet.
Not sure how well it performs, but I would be surprised if any custom code would beat it.
Something like this:) with a different prime number:)
public override int GetHashCode()
{
unchecked
{
int hash = 23;
// Suitable nullity checks etc, of course :)
hash = hash * 31 + Start.GetHashCode();
hash = hash * 31 + End.GetHashCode();
return hash;
}
}
This is not the fastest implementation but it produces a good hash code. Joshua bloch indicates that as well and you also calculate the performance, ^ is usually faster. correct me if i m wrong.
See Jon Skeets impl for c# :
Just as it might help someone in the future that uses visual studio pro (not sure if this also exist in community edition)
You can use the method from Effective Java as Jon Skeet shows here. For your specific type:
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
hash = hash * 23 + Start.GetHashCode();
hash = hash * 23 + End.GetHashCode();
return hash;
}
}
I would trust Microsoft's implementation of GetHashCode() at the tuples and use something like this without any stupid magic:
public override int GetHashCode()
{
Tuple.Create(x, y).GetHashCode();
}
Since DateTime.GetHashCode is internally based on Ticks, what about this:
public override int GetHashCode()
{
return unchecked((int)(Start.Ticks ^ End.Ticks));
}
Or, since you seem to be interested by the date parts (year, month, day), not the whole thing, this implementation uses the number of days between the two dates and should give almost no collision:
public override int GetHashCode()
{
return unchecked((int)Start.Date.Year * 366 + Start.Date.DayOfYear + (End.Date - Start.Date).Days);
}