可以使字典中的第一個類型成爲引用類型? 如果是的話,那是什麼意思?字典中的引用類型
using System.Collections.Generic;
...
Dictionary<T1, T2> myDict = new Dictionary<T1, T2>();
據我所知,第一種類型 - 是關鍵。而且比int或string更經常。
可以使字典中的第一個類型成爲引用類型? 如果是的話,那是什麼意思?字典中的引用類型
using System.Collections.Generic;
...
Dictionary<T1, T2> myDict = new Dictionary<T1, T2>();
據我所知,第一種類型 - 是關鍵。而且比int或string更經常。
使用引用類型作爲字典中的鍵是很好的。重要的是要記住,如果你這樣做,是引用類型使用引用相等作爲默認值。
如果您希望鍵類型的多個實例表示相同的值,那麼您需要確保引用類型使用值相等。例如,string
是一個已經支持值相等的引用類型,因此使用字符串作爲密鑰是安全和容易的。
問題:
以下引用類型沒有實現價值的平等:
class Foo
{
public int X { get; set; }
}
所以,如果你創建兩個實例,拿着同樣的價值,他們不認爲是相等的:
var a = new Foo { X = 1 };
var b = new Foo { X = 1 };
Console.WriteLine(a == b); // false
Console.WriteLine(a.Equals(b)); // false
如果您使用a
作爲關鍵字將值存儲在字典中,那麼您將不會被abl e。使用b
找回它:
var dict = new Dictionary<Foo, int>();
dict[a] = 10;
Console.WriteLine(dict[b]); // Key not found exception
解決方案
爲了解決這個問題,你可以(我)實現價值平等的類型,或(II)重寫你的字典比較鑰匙的方式:
選項I:實現價值的平等:
所以,如果你是要實現價值的平等,供您參考鍵入您應該遵循these guidelines,這會給你這樣的事情(不要忘記GetHashCode
):
class Foo2 : IEquatable<Foo2>
{
public int X { get; set; }
public override bool Equals(object obj)
{
return this.Equals(obj as Foo2);
}
public bool Equals(Foo2 other)
{
if (Object.ReferenceEquals(other, null))
{
return false;
}
// Optimization for a common success case.
if (Object.ReferenceEquals(this, other))
{
return true;
}
if (this.GetType() != other.GetType())
return false;
return (X == other.X);
}
public override int GetHashCode()
{
return this.X;
}
public static bool operator ==(Foo2 lhs, Foo2 rhs)
{
if (Object.ReferenceEquals(lhs, null))
{
if (Object.ReferenceEquals(rhs, null))
{
return true;
}
return false;
}
return lhs.Equals(rhs);
}
public static bool operator !=(Foo2 lhs, Foo2 rhs)
{
return !(lhs == rhs);
}
}
現在表示相同值的Foo2
兩個實例被認爲是相等:
var c = new Foo2 { X = 1 };
var d = new Foo2 { X = 1 };
Console.WriteLine(c == d); // true
Console.WriteLine(c.Equals(d)); // true
如果使用c
作爲密鑰將值存儲在字典中,則您的將能夠使用d
檢索它:
var dict = new Dictionary<Foo2, int>();
dict[c] = 10;
Console.WriteLine(dict[d]); // 10
方案二:使用自定義相等比較:
如果你不打算通常比較Foo
情況,但還是希望能夠在字典中的比較時他們使用的值相等,就可以提供自定義相等比較器,以替代實現全部價值的平等:
class FooComparer : IEqualityComparer<Foo>
{
public bool Equals(Foo x, Foo y)
{
// Doesn't handle null arguments!
return x.X == y.X;
}
public int GetHashCode(Foo obj)
{
return obj.X;
}
}
a
和b
仍然被認爲是不相等的,但現在你可以使用存儲在詞典中值,並採用b
檢索:
var dict = new Dictionary<Foo, int>(new FooComparer());
dict[a] = 10;
Console.WriteLine(dict[b]); // 10
+1爲完整樣本...另外改變一個類型只是爲了能夠用作字典中的鍵可能是矯枉過正,考慮實施'IEqualityComparer
@AlexeiLevenkov好點。我也添加了該選項的示例。 – Ergwun
在.NET框架中的每個對象有GetHashCode
和Equals
方法。而這些都是需要用作字典中的關鍵字。
默認引用類型使用引用相等(即鍵是內存中的同一對象),但您可以覆蓋GetHashCode
和Equals
以提供您喜歡的任何相等語義。
+1。準確地說,即使在類型上實現'GetHashCode'和'Equals'方法也是不必要的 - [Dictionary(IEqualityComparer
是的,你可以使用引用類型作爲'TKey'。它實際上並不重要,如果它是一個結構或一個類。我不明白你爲什麼認爲它沒有意義。 – MarcinJuraszek
嘗試一下,看看它是否可能。 –
你知道'string'是一個類(也就是引用類型),對吧? –