我无法从模板字典创建类实例的副本。似乎MemberwiseClone()
留下了一些引用字典模板字段的字段。我希望能够以一种方便的方式查看是否如此,就像 Visual Studio 的 DataTips 提供的那样。
有没有办法找出引用类型对象(或其字段)的实例是否正在引用相同类型的另一个实例(在成员克隆之后)?
我无法从模板字典创建类实例的副本。似乎MemberwiseClone()
留下了一些引用字典模板字段的字段。我希望能够以一种方便的方式查看是否如此,就像 Visual Studio 的 DataTips 提供的那样。
有没有办法找出引用类型对象(或其字段)的实例是否正在引用相同类型的另一个实例(在成员克隆之后)?
规则是任何值类型都将被复制,任何引用类型只会复制引用。这是一个浅拷贝。
如果这不是您想要的行为,那么您需要推出自己的克隆方法。
您可能正在谈论深拷贝,在这种情况下,这将告诉您需要了解的内容:如何在 .NET(特别是 C#)中对对象进行深拷贝?
至于计算对实例的引用数,Eric Lippert 说 C# 不做引用计数C# - 获取对对象的引用数,所以你必须再次自己动手。但我不认为这是你想要做的。
您可以使用内存分析器手动检查引用。请参阅.NET 内存分析工具。
Java 的一个“特性”是实际上只有一种非原始类型:对象引用,它可以以各种方式使用。虽然这使框架易于实现,但这意味着变量的类型不足以描述其含义。尽管 .net 在许多方面都对 Java 进行了改进,但它也存在着这个根本性的弱点。
例如,假设一个对象George
有一个Bob
类型为IList<String>
[or, for Java, list<string>
] 的字段。这样一个字段至少可以代表五种根本不同的事物:
简而言之,可以Bob
封装列表的可变状态、它的身份、两者或两者都不封装(除了身份之外的不可变状态是“免费赠品”)。如果它仅封装可变状态,则语义正确的副本George
必须Bob
引用不同的列表,该列表使用相同的内容进行初始化。如果它仅封装身份,则语义正确的副本必须Bob
引用相同的列表。如果它同时封装了可变状态和不可变状态,George
则无法单独正确克隆。两者都不做的字段可以被复制也可以不被复制,以方便起见。
如果可以正确确定哪些字段封装了引用对象的可变状态,哪些封装了身份,哪些两者兼而有之,那么语义上正确的克隆操作应该做什么就很明显了。不幸的是,框架中没有以这种方式对字段进行分类的标准约定,因此您必须提出自己的方法,然后再提出使用它的克隆方案。