Re: Key compare in Dictionary
Mike Andrews <[email protected]> Thu, 20 May 2010 05:49:44 -0500
| Newsgroups | gmane.comp.windows.devel.dotnet.advanced |
|---|---|
| Message-ID | <[email protected]> |
You need to override GetHashCode and Equals. It needs to look something
like this:
public class KeyData : IEquatable<KeyData> {
public string F1 { get; set; }
public int F2 { get; set; }
public KeyData(string f1, int f2) {
F1 = f1;
F2 = f2;
}
public bool Equals(KeyData other) {
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Equals(other.F1, F1) && other.F2 == F2;
}
public override bool Equals(object obj) {
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != typeof(KeyData)) return false;
return Equals((KeyData)obj);
}
public override int GetHashCode() {
unchecked {
return ((F1 != null ? F1.GetHashCode() : 0) * 397) ^ F2;
}
}
public static bool operator ==(KeyData left, KeyData right) {
return Equals(left, right);
}
public static bool operator !=(KeyData left, KeyData right) {
return !Equals(left, right);
}
}
On Thu, May 20, 2010 at 5:32 AM, David Nicholson <[email protected]>wrote:
> I am using a class as a key to a Dictionary, and the key comparisons are
> not working as I expect. The example below illustrates:
>
> // This is the key of the dictionary
> namespace DictionaryTest
> {
> using System;
> public class KeyData : IEquatable<KeyData>
> {
> public string F1 { get; set; }
> public int F2 { get; set; }
>
> public KeyData(string f1, int f2)
> {
> F1 = f1;
> F2 = f2;
> }
>
> bool IEquatable<KeyData>.Equals(KeyData other)
> {
> if (String.Compare(F1, other.F1, true) != 0)
> return false;
>
> if (F2 != other.F2)
> return false;
>
> return true;
> }
> }
> }
>
> and I am using it like this:
>
> namespace DictionaryTest
> {
> using System;
> using System.Collections.Generic;
> class Program
> {
> static void Main(string[] args)
> {
> var d1 = new Dictionary<KeyData, int>();
>
> d1.Add(new KeyData("a", 1), 1);
> d1.Add(new KeyData("b", 1), 1);
>
> KeyData kd = new KeyData("a", 1);
>
> string mesg;
> if (d1.ContainsKey(kd))
> mesg = "Found";
> else
> mesg = "Not found";
>
> Console.WriteLine(mesg);
> }
> }
> }
>
> This always returns "Not found", which isn't what I expect. A breakpoint on
> KeyData.Equals is never reached. The documentation for dictionary includes:
>
> "If type TKey implements the System .IEquatable <T> generic interface, the
> default equality comparer uses that implementation"
>
> I wrote an IEqualityComparer<KeyData> and passed that to the dictionary
> constructor, and it works as I expect.
>
> Thanks
> David.
>
> ===================================
> View archives and manage your subscription(s) at
> http://peach.ease.lsoft.com/archives
>
===================================
View archives and manage your subscription(s) at http://peach.ease.lsoft.com/archives