0

I have classes :

public class ComplexObject
{
 public int number = 12;
 public anotherComplexObject aco;
}

public class Experiment
{
  public ComplexObject GetDeepCopyObj(ComplexObject obj)
  {
     var copiedData = new ComplexObject 
     {
            number = obj.number,
            aco = obj.aco
     };
      
     return copiedData ;
  }
  
  static void Main()
  {
   ComplexObject c1 = new ComplexObject();
   c1.number = 3;
   c1.aco = new anotherComplexObject{...};

   Experiment experiment = new Experiment();
   ComplexObject c2 = experiment.GetDeepCopyObj(c1); //line 99
  }
}

Here, when i make a call to GetDeepCopyObj(c1) in "line 99", will c2 be a deep copied object of c1 in c#(aco field is reference type..Still it will have same reference right? i am assuming a deep copy will not happen here)?

Mr.Curious
  • 282
  • 1
  • 3
  • 11
  • 1
    As the term implies, a *deep copy* will create a completely new instance **down the entire oject-graph**. So when your `ComplexObject` has some `anotherConplexObject` in it, you should deep-copy that as well until the most atomic data-structures, which eventually will be value-types and strings. – MakePeaceGreatAgain Mar 28 '23 at 05:45
  • A shallow copy is one where every reference field or property refers to the same object as the original. A deep copy is anything else, so there's no one way to create a deep copy. If you create a copy of the object referred to by one field or property then it's a deep copy. There's no rule about how many fields or properties that you have to copy or how many levels down you have to go. – jmcilhinney Mar 28 '23 at 05:46
  • @MakePeaceGreatAgain, that's simply not true. If that were really the case then there would be many cases where you'd end up in a cycle of copying the same objects. A deep copy is literally anything that isn't a shallow copy. It is probably most usual for a deep copy to copy every reference type field or property to one level deep but that's not a rule. – jmcilhinney Mar 28 '23 at 05:47
  • @jmcilhinney how would you else deep-copy something if not by copying the entire object graph? Your argument makes no sense to me. – MakePeaceGreatAgain Mar 28 '23 at 05:49
  • 1
    @MakePeaceGreatAgain, if you assume that "deep copy" means copying the entire graph, as you seem to be, then you couldn't. If you assume that "deep copy" means copying the object referred to by one or more reference type fields or properties to at least one level deep then the answer to your question is trivial and the question doesn't need to be asked. If we assume you're correct, what happens if that object graph contains a cycle? What happens if two branches of the graph merge on a single object? – jmcilhinney Mar 28 '23 at 05:57
  • @jmcilhinney I assume you need to handle that case the exact same way as you created the cycle in the first place. Why should there be a difference in creating a new instance of my object depending on if I deep-copy it or not? In other words: cycles aren't a concern of copying objects, but of creating them in the first place. – MakePeaceGreatAgain Mar 28 '23 at 05:59

2 Answers2

2

In your example, your c1 object is one object on your heap. It has a pointer to a second object (c1.aco) on your heap. In your particular deep copy implementation, you are creating a new object c2. This will be a separate object on the heap, but in this case, its aco property will still point to the original aco object (eg, c1.aco == c2.aco). I would consider your current implementation to be somewhere between a shallow copy and true deep copy (based on the other comments though, it seems this opinion is not necessarily shared).

I don't understand the second part of your question - I'm not a CPP expert, but I'm not familiar with a getObjId() method, and Google isn't finding much for me either. Can you elaborate on what you mean by objId and maybe what you want to do with it?

Jake
  • 862
  • 6
  • 10
  • In cpp we can get unique id for an object using getObjId. Sine memory is handled by runtime in c# , address keeps on changing. So how do we get the objid of an object in c# at any instance of time was the question – Mr.Curious Mar 28 '23 at 05:52
  • @Mr.Curious do you mean the pointers *adress* here? Which isn't an id. Anyway that won't change in C# once your object was created. However why do you care? Usually you don't need to know where an object is stored in C#. – MakePeaceGreatAgain Mar 28 '23 at 05:56
  • 2
    I still don't see any documentation for a function called `getObjId`, in any language. Regardless though, this question would seem to be addressed by [this post](https://stackoverflow.com/questions/750947/net-unique-object-identifier), one way or another. – Jake Mar 28 '23 at 05:56
1

aco field is reference type..Still it will have same reference right? i am assuming a deep copy will not happen here)

Yes, that's what reference-types are about and therefor your aco-property of both c1 and c2 will reference the exact same object.

A deep copy, as the term implies, will create a completely new instance down the entire oject-graph. So when your ComplexObject has some anotherConplexObject in it, you should deep-copy that as well until the most atomic data-structures, which eventually will be value-types and strings.

As per ypur second question: I don't know of any global function getObjId for any object, that returns the objects id, as not all classes share the concept of an id at all. What you presumably mean is the pointers adress, which is where the object is stored physically. This concept has nothing to do with an id, though.

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111