我无法从模板字典创建类实例的副本。似乎MemberwiseClone()
留下了一些引用字典模板字段的字段。我希望能够以方便的方式查看是否这样,就像Visual Studio的DataTips提供的那样。
有没有办法找出引用类型对象(或其字段)的实例是否引用了同一类型的另一个实例(在成员克隆之后)?
答案 0 :(得分:2)
规则是将复制任何值类型,并且任何引用类型将仅复制引用。这是一个浅薄的副本。
如果这不是你想要的行为,那么你需要推出自己的克隆方法。
您可能正在谈论深层复制,在这种情况下,这将告诉您需要了解的内容:How do you do a deep copy of an object in .NET (C# specifically)?
至于计算实例引用的数量,Eric Lippert说C#不会引用引用计数C# - Get number of references to object,所以你再次必须自己动手。但我认为这不是你想做的事。
答案 1 :(得分:0)
您可以使用内存分析器手动检查引用。请参阅.NET Memory Profiling Tools。
答案 2 :(得分:0)
Java的一个“特性”是,实际上只有一种非基本类型:对象引用,可以以各种方式使用。虽然这使得框架易于实现,但这意味着变量的类型不足以描述其含义。虽然.net在很多方面改进了Java,但它分享了这个根本的弱点。
例如,假设对象George
的字段Bob
的类型为IList<String>
[或者,对于Java,list<string>
]。至少有五个根本不同的东西,如一个领域可以代表:
简而言之,Bob
可以封装列表的可变状态,其身份,两者或两者(不可变状态,除了身份,是'免费赠品')。如果它仅封装可变状态,则George
的语义正确副本必须具有Bob
引用不同的列表,该列表使用相同的内容进行初始化。如果它仅封装标识,则语义正确的副本必须Bob
引用相同的列表。如果它封装了可变状态和不可变状态,则George
无法单独克隆。可以复制或不复制的字段,方便。
如果可以正确地确定哪些字段封装了引用对象的可变状态,哪些字段封装了身份,哪些封装了两者,那么语义正确的克隆操作应该做什么。遗憾的是,框架中没有以这种方式对字段进行分类的标准约定,因此您必须提出自己的方法,然后是使用它的克隆方案。