?
Solved

Copy object without creating new instance

Posted on 2009-02-22
10
Medium Priority
?
3,212 Views
Last Modified: 2013-12-17
I have need to copy an object without creating a new instance of it.  (i.e. DeepClone and Serialize won't do it)  Example:

I have a routine for editing an object's content.  I start by making a copy of the object, (that can be a new instance) then I change it's values, apply, change value, apply, etc.  At some point I want to revert the original object back to its initial state.  I can't use DeepClone against the copy because I need to return the same object that was passed in.  

Note: this is just an example, I've got lots of cases where I need to repopulate an object's content without re-instantiating it.  (i.e. any place where other routines have an handle to that instance of the object)

It seems to me that the code in DeepClone and Serialize must be able to do this, but I haven't see that code and so don't know what to call.

thanks!
0
Comment
Question by:pdprog
10 Comments
 
LVL 37

Assisted Solution

by:gregoryyoung
gregoryyoung earned 150 total points
ID: 23706273
problem:

you need the same "instance" as before changes.


answers:
a) use the memento pattern http://en.wikipedia.org/wiki/Memento_Pattern but this can be annoying/costly
b) when you do a deep copy start making changes on your copy (not on the original object) then on "commit" replace the original with the copy.
c) use a deep copy but have the other areas hold a proxy of the internal object (then you can change which object the proxy is looking at transparently to the other code)

A better question might be ... do the other things *really* need to be holding an instance of this object.

Cheers,

Greg
0
 
LVL 30

Accepted Solution

by:
anarki_jimbel earned 300 total points
ID: 23706333
"It seems to me that the code in DeepClone and Serialize must be able to do this..."

Really Serialization sometimes is proposed as a method for a deep cloning. And when cloning - you get a new object. So from what you stated (your task) the above is not the way. Serialization - deserialization process also gives you a new object.

So you need something else. I'm not sure because it depends on your object  but e.g. you use some custom structures to teporarily store previous object settings. Or might be you can create another instance as a clone of your object but when necessary - copy all properties from the clone back to the original object.
0
 

Author Comment

by:pdprog
ID: 23706387
Thanks Greg,

I appreciate the insights.

The "momento pattern" is a solution for my specific example, though not for the general case of wanting to be able to load settings into an exiting object.  Also, the article "momento pattern" basically does all the work manually to reset the original object.

option (c) seems like quite a hack - a workaround to accomplish what I'm looking for.  But I don't want to make a whole bunch of proxy objects.

My existing code contains methods like this for pretty much every object::

public class MyClass
  private string string1;
  private int int1;

  public void CopyFrom( MyClass aClass )
  {
     string1 = aClass.string1;
     int1 = aClass.int1;
  }
...

This code will work just fine, but since deepClone exists, as well as the serialization using reflection, I figured it would be better to use code like that rather than manually copying all the properties.

From your answer, it sounds like I'll have to use my existing "manual" process.

As for the "better question".  As I said, this was only one example.  How about another like this:  I've got a simple utility application that's got several tabs, dialogs and a number of objects.  There is a settings object that contains values used by the various dialogs and other objects.  The other objects and dialogs hold a pointer to the settings.  At any time, those objects may receive a "refresh" notification.  In response, they look at the settings and update themselves.  So, now I implement loadSettings() and and saveSettings().  When loadSettings() is called, the settings properties get changed and "refresh" is called against all active dialogs and objects.  Can't do that if the object just got changed out from under.  right?

Thanks again,

-Pete
0
NEW Veeam Backup for Microsoft Office 365 1.5

With Office 365, it’s your data and your responsibility to protect it. NEW Veeam Backup for Microsoft Office 365 eliminates the risk of losing access to your Office 365 data.

 

Author Comment

by:pdprog
ID: 23706412
Dmitry,
Thanks.

... Or might be you can create another instance as a clone of your object but when necessary - copy all properties from the clone back to the original object.

It's that "copy all properties..." part that I'm trying to accomplish without writing all the code manually.  

Doesn't it seem likely that the DeepClone code could do something like this:

if( ProvidedObject )
  return ProvidedObject.DeepClone( this );
else
  return new <objecttype>.DeepClone( this);

I figure inside the DeepClone method, there is a line that creates a new instance and then all work is done with that new instance.  Seems like one could just take an existing instance and work from there, no?
Thanks.

-Pete



0
 
LVL 30

Expert Comment

by:anarki_jimbel
ID: 23706515
Hmmm, could you tell me pls what class are you using? I mean to what class the DeepClone method belongs? Am I missing something?
0
 

Author Comment

by:pdprog
ID: 23706571
Dmitry - truth is, I've been looking at Deserialize this whole time.  Just from googling and reading docs, it appears that one can implement ICloneable and get the ability to do a "deep clone".  I just assumed that was actually a function name.

I guess what I am specifically looking for is a way to implement a CopyFrom( myObjectType m ) method without having to write all the copy code.  It seems that since reflection is being used to create a *new* object in serialization, it could be used to populate an existing one as well.

Every response I've received from my own resources has suggested that *I'm* the one missing something :-0  but I'm not quite ready to let it go.

Thanks for any insights.

-Pete
0
 

Author Comment

by:pdprog
ID: 23706583
BTW: the source of this problem is that I'm porting about 300,000 lines of my own Delphi code to C# right now.  All of my objects include a LoadFromXML( aNode ) function and CopyFrom( aObject ) functions.  I can certainly port those methods over from Delphi to C#, I'm just trying reduce my rote typing by using existing library functionality.

-Pete
0
 
LVL 86

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 300 total points
ID: 23706737
It sounds like you just need to use straight REFLECTION to enumerate all the user defined members in your class and copy all the values over from the "stored" instance...
0
 

Author Comment

by:pdprog
ID: 23706810
A friend just Skyped me this,and followed it with an example for loading from XML as well.  I just have to convert it to C#,  build a static class and a framework for doing a "deep" copy.  And I'm on my way.

method Foo.CopyFrom(ASource: Foo);
begin
  var LClassFields := self.GetType().GetFields( BindingFlags.NonPublic + BindingFlags.Public + BindingFlags.Instance);
  for field in LClassFields do begin
    field.SetValue(self, field.GetValue(ASource))
  end;
end;

He doesn't have an account here, so I'll split the points across all three of you:

Greg for the most "almost" answers :)
Dmitry for understanding the problem
Idle Mind for the right answer without telling me how to do it!  ;)

Thanks guys!

-Pete

0
 
LVL 30

Expert Comment

by:anarki_jimbel
ID: 23706821
Agree to Idle_Mind, I think reflection is what you need. How to copy property values from one object to another:

http://www.eggheadcafe.com/tutorials/aspnet/a4264125-fcb0-4757-9d78-ff541dfbcb56/net-reflection--copy-cl.aspx

The algorithm probably is not very efficient but it will do the job.

Still you will may need some additional instance to store original values...
0

Featured Post

Veeam Disaster Recovery in Microsoft Azure

Veeam PN for Microsoft Azure is a FREE solution designed to simplify and automate the setup of a DR site in Microsoft Azure using lightweight software-defined networking. It reduces the complexity of VPN deployments and is designed for businesses of ALL sizes.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…
Suggested Courses

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question