Reputation: 1687
In my class, I have implemented Equals
and GetHashCode
. yet when I use it as key for a dictionary in my C# code, I get the error : "Key not found exception"
Thanks,
public class Time: IEquatable<Time>
{
public String hour;
public String minute;
public Time()
{
hour = "00";
minute = "00";
}
public Time(String hour, String minute)
: this()
{
this.hour = hour;
this.minute = minute;
}
public override int GetHashCode()
{
int hash = int.Parse(hour) * 60 + int.Parse(minute);
return hash.GetHashCode();
}
public override bool Equals(Time time)
{
return (this.hour == time.hour && this.minute == time.minute);
}
}
And The code where I am using it:
Dictionary<Time, int> time2RowIndex = new Dictionary<Time, int>();
...
int beginRow = 0;
if(time2RowIndex.ContainsKey(time.hour))
beginRow = time2RowIndex [time.hour];
Upvotes: 3
Views: 1483
Reputation: 5649
Try this. The trick is to override Equals
from object (and GetHashCode
) instead of just implementing IEquatable<>
.
Also, if Hour
or Minute
on the Time
object change after the instance of Time
has been added to the dictionary, the bucket (selected by hash code at the time of the add) will no longer match the hash code on the object. This means that even if you present an object of equal value to the dictionary (say with ContainsKey
), it won't find the original item in the dictionary (because the hash bucket it will look in doesn't contain the original object). It's a best practice that all fields referenced in the GetHashCode
function be readonly to avoid these situations.
public class Time : IEquatable<Time>
{
public String Hour;
public String Minute;
public Time()
{
Hour = "00";
Minute = "00";
}
public Time(String hour, String minute)
: this()
{
this.Hour = hour;
this.Minute = minute;
}
public override int GetHashCode()
{
return int.Parse(Hour) * 60 + int.Parse(Minute);
}
public override bool Equals(object obj)
{
var time = obj as Time;
return !ReferenceEquals(time, null) && Equals(time);
}
public bool Equals(Time time)
{
return string.Equals(Hour, time.Hour, StringComparison.Ordinal) && string.Equals(Minute, time.Minute, StringComparison.Ordinal);
}
}
Upvotes: 5