深入了解哈希表的浅拷贝问题

4

我看到了一些关于哈希表浅拷贝和深拷贝的文章/解释,读得越多,就越感到困惑。

Hashtable ht = new Hashtable();
ht.Add("1", "hello");

Hashtable ht2 = new Hashtable();
ht2 = ht;                          // case1: is this shallow copy?
ht2["1"] = "H2";

Hashtable ht3 = new Hashtable(ht); // case2: is this shallow copy?
ht3["1"] = "H3";

Hashtable ht4 = new Hashtable();
ht4 = (Hashtable)ht.Clone();       // case3: is this shallow copy?
ht4["1"] = "H4";
  • Case1: 结果,ht内容更改为与ht2相同。
  • Case2: 结果,ht内容与ht3不同。
  • Case3: 结果,ht内容与ht4不同。

如果Case2和Case3是浅拷贝,那么结果不应该与Case1相同吗?

List、ArrayList等也会发生这种情况吗?


3
顺便提一下,如果您正在使用.NET 3.5,为什么还在使用ArrayList和Hashtable?强烈建议使用通用类型。 - Jon Skeet
嗨@JonSkeet,感谢指出泛型类型。我已经转移到了泛型类型。 - Bo5ku
1个回答

2
在第一种情况下,ht2ht 都指向同一个 Hashtable 实例。
在第二种和第三种情况下,ht3ht4 指向通过复制原始的 Hashtable 条目所创建的不同对象
请注意,即使进行“深层”拷贝(创建新的映射),您仍然会复制引用。例如:
var original = new Dictionary<int, StringBuilder>();
original[10] = new StringBuilder();

var copy = new Dictoinary<int, StringBuilder>(original);
copy[20] = new StringBuilder();

// We have two different maps...
Assert.IsFalse(original.ContainsKey(20));

// But they both refer to a single StringBuilder in the entry for 10...
copy[10].Append("Foo");
Assert.AreEqual("Foo", original[10].ToString());

直到你在这里指出了这个行为(并且给出了一个很好的例子),我才意识到它。谢谢。 - Bo5ku

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接