Link to home
Start Free TrialLog in
Avatar of pdprog
pdprogFlag for United States of America

asked on

Copy object without creating new instance

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!
SOLUTION
Avatar of gregoryyoung
gregoryyoung
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Avatar of Dmitry G
Dmitry G
Flag of New Zealand image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of pdprog

ASKER

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
Avatar of pdprog

ASKER

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



Hmmm, could you tell me pls what class are you using? I mean to what class the DeepClone method belongs? Am I missing something?
Avatar of pdprog

ASKER

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
Avatar of pdprog

ASKER

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
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of pdprog

ASKER

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

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...