.NET:字典的值是按引用还是按值存储的?

25

我有一个Dictionary<int, Product>。如果同一个Product被添加到多个键中,那么每个键会存储一个新的实例对象,还是仅存储对原始对象的引用?

这个集合非常大,每个产品将有1-10个键与之关联。我的主要担忧是内存分配。

4个回答

38
如果“Product”是一个引用类型(class而不是struct),则只会存储引用。

如果它是一个元组<string,string>会怎样? - NSjonas
如果我从数据库加载一个大列表,然后创建3个不同的字典以便在不同的变量上进行索引,那么这不会占用内存大小*4(列表,3个字典)吗? - MIKE

5

不,它应该使用相同的原始对象引用。

但是,如果对字典进行序列化/反序列化,我不太确定它会如何行为。


除非您编写自己的逻辑来处理它,否则无法对字典进行序列化/反序列化,因为它不受默认支持。 - eandersson
3
上述评论可能在2年前是真实的,但现在不再如此。标准的.NET序列化/反序列化器似乎相当好地处理字典,至少在.NET 4.0及以上版本中如此。 - DaveN59

5
Dictionary会存储您传递给它的键的值的副本。对于它或任何其他集合/容器来说,存储对任何值的引用是不可能的,因为容器可能会比您试图存储在其中的变量存在更长的时间。
现在,正如其他人所说,如果值的类型是引用类型,则变量的值只是一个引用,因此您只是存储了对变量的引用的副本。如果字典的值的类型是值类型,则实际值将被复制。

如果键和值是类,则两者都是引用而不是复制。 - Sebastian 506563
1
@Taumantis 正如我在答案中提到的那样,如果变量是引用类型,则存储的是引用的副本。这不是存储对变量的引用。说值是按引用复制的或者存储了对变量的引用是不正确的。变量的值被复制,无论该值是什么。如果该值本身是一个引用,那么就会复制它。 - Servy

0

引用类型始终以引用的方式存储。没有人会猜测你对类型的"克隆"逻辑的意图。如果你需要复制,你必须在放入容器、传递给其他函数等之前自己创建副本。

值类型会被复制(简单地复制字节表示,但所有引用值仍将是引用),除非作为引用传递给函数。对于容器来说,它们会成为副本。除非你为它们创建一个引用类型的包装器。


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