我有这个简单的例子:
using System; using System.Collections.Generic; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Dictionary<MyKey,string> data = new Dictionary<MyKey,string>(); data.Add(new MyKey("1","A"),"value 1A"); data.Add(new MyKey("2","value 2A"); data.Add(new MyKey("1","Z"),"value 1Z"); data.Add(new MyKey("3","value 3A"); string myValue; if (data.TryGetValue(new MyKey("1",out myValue)) Console.WriteLine("I have found it: {0}",myValue ); } } public struct MyKey { private string row; private string col; public string Row { get { return row; } set { row = value; } } public string Column { get { return col; } set { col = value; } } public MyKey(string r,string c) { row = r; col = c; } } }
这工作正常但是如果我以这种方式用MyKey类更改MyKey结构:
public class MyKey
然后方法TryGetValue没有找到任何键,尽管关键是在那里.
我相信我错过了一些明显的东西,但我不知道什么.
任何想法 ?
谢谢
**解决方案**
(请参阅获取更好的GetHashCode解决方案的解决方案)
我已经重新定义了MyKey类,所有这一切都正常工作:
public class MyKey { private string row; private string col; public string Row { get { return row; } set { row = value; } } public string Column { get { return col; } set { col = value; } } public MyKey(string r,string c) { row = r; col = c; } public override bool Equals(object obj) { if (obj == null || !(obj is MyKey)) return false; return ((MyKey)obj).Row == this.Row && ((MyKey)obj).Column == this.Column; } public override int GetHashCode() { return (this.Row + this.Column).GetHashCode(); } }
感谢所有的人回答了这个.
解决方法
您需要覆盖类MyKey中的Equals()和GetHashCode()
也许这样的事情:
GetHashCode的()
public override int GetHashCode() { return GetHashCodeInternal(Row.GetHashCode(),Column.GetHashCode()); } //this function should be move so you can reuse it private static int GetHashCodeInternal(int key1,int key2) { unchecked { //Seed var num = 0x7e53a269; //Key 1 num = (-1521134295 * num) + key1; num += (num << 10); num ^= (num >> 6); //Key 2 num = ((-1521134295 * num) + key2); num += (num << 10); num ^= (num >> 6); return num; } }
等于
public override bool Equals(object obj) { if (obj == null) return false; MyKey p = obj as MyKey; if (p == null) return false; // Return true if the fields match: return (Row == p.Row) && (Column == p.Column); }