Object类提供了一些virtual方法,例如ToString, GetHashCode, Equals等,通常我们不太体会它的意义。而Dictionary中的Key却需要也帮助我们很好的理解这些方法。
- Key满足set属性,即其中的元素不可重复;(应用了Equals方法)
- Key-Value的映射是通过Key的哈希值来实现的;(应用了GetHashCode方法)
1) string作为key (string虽然是reference type,但这里作为值类型来进行比较是否相等)
string myKey = "TheUniqueKey";
string myKey2 = "TheUniqueKey";
Dictionary<string, object> myDictionary = new Dictionary<string, object>();
myDictionary.Add(myKey, new Book { Title = "C#" });
//myDictionary.Add(myKey2, new Book { Title = "VB" });
最后一行会报错,因为myKey与myKey2其实是相等的。
2) Reference type作为key。一种是object没有覆盖Equals方法则以内存地址判断,一种是依赖Equals方法。
internal class Book
{
public string Title { get; set; }
public override string ToString()
{
return Title;
}
public override int GetHashCode()
{
return Title.GetHashCode();
}
//public bool Equals(Book other)
//{
// if (other == null)
// return false;
// if (this.Title == other.Title)
// return true;
// else
// return false;
//}
//public override bool Equals(Object obj)
//{
// if (obj == null)
// return false;
// Book personObj = obj as Book;
// if (personObj == null)
// return false;
// else
// return Equals(personObj);
//}
}
- 第一种情况:假设没有提供Equals方法即注释掉相应的代码
Book csharp=new Book{Title="C#"};
Book vb=new Book{Title="C#"};
Dictionary<Book, string> dic = new Dictionary<Book, string>();
dic.Add(csharp, "csharp");
dic.Add(vb, "vb");
try
{
string book;
dic.TryGetValue(csharp, out book);
Console.WriteLine("The book title is {0}.",book);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
The output is "The book title is csharp."
- 第二种情况:提供Equals方法
上述代码会抛出异常,"Unhandled Exception: System.ArgumentException: An item with the same key has already been added."
3) 注释掉GetHashCode方法不影响此例的映射操作。一个问题就是如果没有此方法.NET是如何计算哈希值的?
第二个问题就是开发人员最好仔细考虑此方法以便提高Dictionary操作的性能。