Question

I'm having trouble creating copies of my class instances from a dictionary of templates. It appears that MemberwiseClone() leaves some fields referenced to the dictionary's template fields. I'd like to be able to see if that's so in a convenient way, like Visual Studio's DataTips provide.

Is there a way to find out if an instance of a reference type object (or its fields) is referencing another instance of the same type (after memberwise cloning)?

Was it helpful?

Solution

The rule is that any value type will be copied and any reference type will only copy the reference. It is a shallow copy.

If that is not the behaviour that you want then you need to roll your own clone method.

You are probably talking about a deep copy, in which case this will tell you what you need to know: How do you do a deep copy of an object in .NET (C# specifically)?

As for counting the number of references to an instance, Eric Lippert says that C# does not do reference counting C# - Get number of references to object so again you would have to roll your own. But I don't think that is what you want to do.

OTHER TIPS

You could use a memory profiler for manually checking the references. See .NET Memory Profiling Tools.

One "feature" of Java is that there's really only one non-primitive type: an object reference, which may be used in all sorts of ways. While that makes the framework easy to implement, it means that the type of a variable is insufficient to describe its meaning. While .net improves on Java in many ways, it shares that fundamental weakness.

For example, suppose an object George has a field Bob of type IList<String> [or, for Java, list<string>]. There are at least five fundamentally different things such a field could represent:

  1. It holds a reference to an object holding a set of strings to which it will never allow any changes. If item #5 of that list is "Barney", then item #5 on that list will never be anything other than "Barney". In this scenario, `Bob` encapsulates only immutable aspects of the list. Further, the reference may be freely shared to any code that's interested in that aspect of George's state.
  2. It holds a reference to an object holding a set of strings which may be modified by anyone holding a reference, but no entity with a reference to that object will modify the list nor allow it to be exposed to anything that might do so. In other worse, while the list would allow its contents to be changed, nothing will in fact ever alter those contents. As above, `Bob` encapsulates only immutable aspects of the list, but `George` is responsible for maintaining such immutability by exposing the reference only to code that can be trusted not to modify the list.
  3. It holds the only reference, anywhere in the universe, to an object holding a set of strings which it modifies at will. In this scenario, `Bob` encapsulates the *mutable state* of the list. If one copies `George`, one must make a new list with the same items as the old, and give the copy a reference to that. Note also that `George` cannot pass a reference to any code that might persist the reference, whether or not that code would try to modify the list.
  4. It holds a reference to a list which is "owned" by some other object, which will be used either to add items to the list for the other object's benefit, or to observe things the other object has put in the list for `George`'s benefit. In this scenario, `Bob` encapsulates the *identity* of the list. In a correct clone, `Bob` must identify the *same list* as in the original.
  5. It holds a reference to a list which it owns, and which will be mutated, but to which some other objects also hold a reference (perhaps so they can add things to the list for `George`'s benefit, or perhaps so they can see things `George` does with the list). In this scenario, `Bob` encapsulates *both mutable state and identity*. The existence of a field which encapsulates both aspects means that *it is not possible to make a semantically-correct copy of `George` without the cooperation of other objects*.

In short, it's possible for Bob to encapsulate the list's mutable state, its identity, both, or neither (immutable state, other than identity, is a 'freebie'). If it encapsulates only mutable state, a semantically-correct copy of George must have Bob reference a different list which is initialized with the same contents. If it encapsulates only identity, a semantically-correct copy must have Bob reference the same list. If it encapsulates both mutable state and immutble state, George cannot be properly cloned in isolation. Fields that do neither may be copied or not, as convenient.

If one can properly determine which fields encapsulate the referenced objects' mutable states, which ones encapsulate identity, and which ones both, it will be obvious what a semantically-correct cloning operation should do. Unfortunately, there's no standard convention in the Framework for categorizing fields in such fashion, so you'll have to come up with your own method and then a cloning scheme that uses it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top