In general, when we try to copy one object to another object, both objects will share the same memory address. It's about how objects are saved in Stack and Heap.
In the case of value types, both address and value stay in the Stack which is very easy to copy but for reference types is different. In a normal assignment, it will only copy the address (which stays in Stack) and both variables pointing to the same data so that if obj1 changes the data it reflects obj2 as well, it Shallow copy. You can do it by wrapping this.MemberwiseClone()
in a class method.
Deep Copy is a process of creating a new object and then copying the fields of the current object to the newly
created object to make a complete copy of the internal reference types so obj2 will point to different addresses of heap memory, they are totally different objects. Keep in mind that deep copy is expensive and most of the time you don't need it because you just allocate more memory, ask: Do I need to create a new object?