C# 字典中的引用类型

C# 字典中的引用类型,c#,dictionary,C#,Dictionary,是否可以将字典中的第一个类型设置为引用类型? 如果是,这有什么意义 using System.Collections.Generic; ... Dictionary<T1, T2> myDict = new Dictionary<T1, T2>(); 使用System.Collections.Generic; ... Dictionary myDict=新字典(); 据我所知,第一种类型是关键。通常情况下,使用引用类型作为字典中的键比使用int或string类型更好。

是否可以将字典中的第一个类型设置为引用类型? 如果是,这有什么意义

using System.Collections.Generic;
...
Dictionary<T1, T2> myDict = new Dictionary<T1, T2>();
使用System.Collections.Generic;
...
Dictionary myDict=新字典();

据我所知,第一种类型是关键。通常情况下,使用引用类型作为字典中的键比使用intstring

类型更好。如果这样做,则需要记住的重要一点是引用类型使用引用相等作为默认值

如果希望键类型的多个实例表示相同的值,则需要确保引用类型使用值相等。例如,
string
是一种已经支持值相等的引用类型,因此使用字符串作为键既安全又容易

问题:

以下引用类型未实现值相等:

class Foo
{
    public int X { get; set; }
}
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;
    }
}
因此,如果创建了两个实例,且它们具有相同的值,则它们不被视为相等:

var a = new Foo { X = 1 };
var b = new Foo { X = 1 };
Console.WriteLine(a == b); // false
Console.WriteLine(a.Equals(b)); // false
var c = new Foo2 { X = 1 };
var d = new Foo2 { X = 1 };
Console.WriteLine(c == d); // true
Console.WriteLine(c.Equals(d)); // true
如果使用
a
作为键将值存储在字典中,则无法使用
b
检索该值:

var dict = new Dictionary<Foo, int>();
dict[a] = 10;
Console.WriteLine(dict[b]); // Key not found exception
var dict = new Dictionary<Foo, int>(new FooComparer());
dict[a] = 10;
Console.WriteLine(dict[b]); // 10
现在,表示相同值的
Foo2
的两个实例被视为相等:

var a = new Foo { X = 1 };
var b = new Foo { X = 1 };
Console.WriteLine(a == b); // false
Console.WriteLine(a.Equals(b)); // false
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
a
b
仍然被认为是不相等的,但现在您可以使用
a
在字典中存储一个值,并使用
b
检索该值:

var dict = new Dictionary<Foo, int>();
dict[a] = 10;
Console.WriteLine(dict[b]); // Key not found exception
var dict = new Dictionary<Foo, int>(new FooComparer());
dict[a] = 10;
Console.WriteLine(dict[b]); // 10
var dict=newdictionary(newfoocomarer());
dict[a]=10;
Console.WriteLine(dict[b]);//10

在.NET framework中,每个对象都有
GetHashCode
Equals
方法。这些都是在字典中用作键所需要的


默认引用类型使用引用相等(即,键是否与内存中的同一对象相同),但您可以覆盖
GetHashCode
Equals
以提供您喜欢的任何相等语义。

是的,您可以将引用类型用作
TKey
。实际上,它是一个结构还是一个类并不重要。我真的不明白你为什么认为它毫无意义。试试看它是否可能。你知道
string
也是一个类(因此也是引用类型),对吧?它是否是引用类型并不重要,因为它使用散列值,对吧?+1。准确地说,即使在类型上实现
GetHashCode
Equals
方法也不是必需的-允许使用任何对象作为键,只要您提供适当的自定义比较器。+1用于完整示例。。。在字典中改变一个只能用作键的类型可能是多余的,考虑执行<代码> IEqualityComparer < /代码>,并使用相应的@ AlexeiLevenkov好点。我还添加了一个该选项的示例。