我最近遇到了关于哈希表的这个问题,并且想知道是否有人知道原因。请参阅下面的小代码示例和输出。
Hashtable temp = new Hashtable();
temp["a"] = ("100")[0].ToString();
temp["b"] = "1";
if(temp["a"] == "1")
Response.Write("1");
else
Response.Write("0");
if(temp["b"] == "1")
Response.Write("1");
else
Response.Write("0");
输出为“01”。为什么不是“11”? temp [“a”]被赋予一个字符串,为什么不实际发生呢?
任何能够向我解释或向我指出可能包含解释的文章的人都会有很大的帮助。这一直困扰着我。
谢谢!
答案 0 :(得分:1)
致电
if(temp["a"] == "1")
将哈希表对象与字符串“1”进行比较,字符串“1”将对象与字符串进行比较。对象的根类型可以是字符串,但比较不会知道。
如果你打电话
if(temp["a"].ToString() == "1")
另一种选择是使用Dictionary<TKey,TValue>
泛型,当您调用TValue
temp["a"]
而不是对象
Dictionary<string,int> temp = new Dictionary<string,int>();
答案 1 :(得分:1)
((object)"1") == "1"[0].ToString()
评估为False
,因为这两个对象具有不同的地址。由于您使用的是非泛型Hashtable类,因此temp["a"]
被强制转换为对象,因此它正在进行相同的比较。
C#不遗余力地使string == string
很好地工作(与Java不同),但是当它不知道你的双方都有一个字符串时就不能这样做。
正如其他人所提到的,你最好使用像Dictionary这样的通用类来维持字符串的强类型,但另一种方法是使用.Equals()
而不是==
。或者在使用==
之前手动将值转换为字符串。
答案 2 :(得分:1)
在这两种情况下,比较都会检查引用相等,而不是内容相等,因为左侧的类型为对象。
temp["a"]
包含对在运行时创建的堆上的字符串“1”的引用,根据定义,它与内存中的 interned 字符串“1”不同正在与之进行比较。所以它运行else-part。
temp["b"]
包含对 interned 字符串“1”的引用,根据定义,它与内存中的 interned 字符串“1”相同正在与之进行比较。所以它运行if-part。
有关详情,请查看“string interning”。