[英]C# Dictionary with a class as key
我的問題基本上與Dictionary.ContainsKey 返回 False相反,但是當使用自定義類作為鍵時,想要 True並且“字典中不存在給定的鍵”錯誤:
我想使用一個中等大小的類作為字典的鍵,並且字典必須通過引用而不是值相等來比較鍵。 問題是,該類已經實現了Equals()
(它正在執行值相等 - 這不是我在這里想要的)。
這是一個用於復制的小型測試類:
class CTest
{
public int m_iValue;
public CTest (int i_iValue)
{
m_iValue = i_iValue;
}
public override bool Equals (object i_value)
{
if (ReferenceEquals (null, i_value))
return false;
if (ReferenceEquals (this, i_value))
return true;
if (i_value.GetType () != GetType ())
return false;
return m_iValue == ((CTest)i_value).m_iValue;
}
}
我還沒有實現GetHashCode()
(實際上我已經實現了,但到目前為止它只返回base.GetHashCode()
)。
現在我創建了一個帶有字典的測試程序,該字典使用此類的實例作為鍵。 我可以毫無問題地向字典添加多個相同的實例,但這只是因為GetHashCode()
返回不同的值才有效:
private static void Main ()
{
var oTest1 = new CTest (1);
var oTest2 = new CTest (1);
bool bEquals = Equals (oTest1, oTest2); // true
var dict = new Dictionary<CTest, int> ();
dict.Add (oTest1, 1);
dict.Add (oTest2, 2); // works
var iValue1 = dict[oTest1]; // correctly returns 1
var iValue2 = dict[oTest2]; // correctly returns 2
int iH1 = oTest1.GetHashCode (); // values different on each execution
int iH2 = oTest2.GetHashCode (); // values different on each execution, but never equals iH1
}
並且每次的哈希值都不同,可能是因為object.GetHashCode()
的計算使用了一些隨機化或一些來自引用句柄的數字(每個對象都不同)。
但是,這個答案為什么在覆蓋 Equals 方法時覆蓋 GetHashCode 很重要? 說GetHashCode()
必須為相等的對象返回相同的值,所以我添加了
public override int GetHashCode ()
{
return m_iValue;
}
之后,我無法再向字典中添加多個相等的對象。
現在,有兩個結論:
GetHashCode()
,哈希值將再次不同,並且可以使用字典。 但是可能存在不小心給兩個相等的對象賦予相同的哈希碼的情況,這會在運行時導致異常,其原因肯定永遠不會被找到。 由於這種(很小但不是零)風險,我不能使用字典。GetHashCode()
,無論如何我都不能使用字典。仍然使用字典的可能性有多大?
像以前很多次一樣,我在寫這個問題時就有了解決方案的想法。
您可以在字典的構造函數中指定一個IEqualityComparer<TKey>
。 .net 框架中有一個,但它是internal sealed
,因此您需要實現自己的:
.NET 中是否有任何類型的“ReferenceComparer”?
internal class ReferenceComparer<T> : IEqualityComparer<T> where T : class
{
static ReferenceComparer ()
{
Instance = new ReferenceComparer<T> ();
}
public static ReferenceComparer<T> Instance { get; }
public bool Equals (T x, T y)
{
return ReferenceEquals (x, y);
}
public int GetHashCode (T obj)
{
return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode (obj);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.