在我的应用程序中,我需要使用自定义对象作为字典的键。问题是按引用比较,就像我们都知道使用值类型时,按值比较比较工作,但是在对象中按引用进行比较,因此即使对象相等,它们也会在内存堆中的不同位置存储,因此返回false
为了做到这一点,我需要重写Equals和GetHashCode方法(如果我错了,我想纠正我)
我重写了Equals方法,它的工作原理是:
bool IsEqual = dictionaryList.Keys.First().Equals(compareKey);
返回true。
我不知道如何在我的情况下重写GetHashCode方法(如果需要)。
我得到的例外:
The given key was not present in the dictionary.
--
给定的键在词典中不存在。
我该如何解决该问题,或者我可能完全以错误的方式完成此任务...
谢谢
using System;
using System.IO;
using System.Threading;
using System.Linq;
using System.Collections.Generic;
public sealed class Program
{
public class Options
{
public string x { get; set; }
public string y { get; set; }
}
public class Data
{
public string myData { get; set; }
}
public class KeyClass
{
public int KeyNumber { get; set; }
public List<Options> Options { get; set; }
public override bool Equals(object obj)
{
KeyClass keyClass = obj as KeyClass;
bool IsKeyNumberEqual = (KeyNumber == keyClass.KeyNumber);
bool IsOptionsEqual = true;
if (!(Options.Count == keyClass.Options.Count) || !IsKeyNumberEqual)
{
IsOptionsEqual = false;
}
else
{
for (int i = 0; i < Options.Count; i++)
{
if (!(Options[i].x == keyClass.Options[i].x) ||
!(Options[i].y == keyClass.Options[i].y))
{
IsOptionsEqual = false;
break;
}
}
}
return (IsKeyNumberEqual && IsOptionsEqual);
}
}
public static void Main()
{
try
{
List<Options> optionsList = new List<Options>();
optionsList.Add(new Options() { x = "x1", y = "y1" });
optionsList.Add(new Options() { x = "x2", y = "y2" });
Data someData = new Data() { myData = "someData" };
Data getData = new Data();
KeyClass dictionaryKey = new KeyClass() { KeyNumber = 1, Options = optionsList };
KeyClass compareKey = new KeyClass() { KeyNumber = 1, Options = optionsList };
Dictionary<KeyClass, Data> dictionaryList = new Dictionary<KeyClass, Data>();
dictionaryList.Add(dictionaryKey, someData);
bool IsEqual = dictionaryList.Keys.First().Equals(compareKey);
getData = dictionaryList[compareKey];
}
catch (Exception ex)
{
string exMessage = ex.Message;
}
}
}
您需要编写一个GetHashCode()
包含有助于该Equals()
方法的所有内容的。
例如:
public override int GetHashCode()
{
unchecked
{
int hash = KeyNumber * 397;
foreach (var opt in Options)
{
hash = hash*23 + opt.x.GetHashCode();
hash = hash*23 + opt.y.GetHashCode();
}
return hash;
}
}
如果为您的Options
类实现GetHashCode(),例如:
public class Options
{
public readonly string x;
public readonly string y;
public override int GetHashCode()
{
return x.GetHashCode() ^ y.GetHashCode();
}
}
然后,您可以写得GetHashCode()
更简单:
public override int GetHashCode()
{
unchecked
{
int hash = KeyNumber * 397;
foreach (var opt in Options)
hash = hash*23 + opt.GetHashCode();
return hash;
}
}
我之前忘记提及的一件重要事情:
最重要的是,将对象放入字典后,不会更改有助于相等性或哈希码的所有字段。
如果在将对象添加到字典后更改其中任何一个,则很可能将不再能够从字典中检索对象。
确保这一点的最佳方法是仅将不可变字段用于相等性和哈希码。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句