Object deep copy

Source: Internet
Author: User

I thought of a method for this problem without any reference.

It's okay to customize some simple types. When it comes to some complicated classes in. net, there is no way to do anything better.

 

 

Class cstod
{
// The basic idea is: the memory space occupied by an object depends on its instance field (including the private instance field on the inheritance tree)
Public t deepcloneobject <t> (t obj) where T: Class
{
// The system. string type seems special. copying all its fields does not support copying itself.
// However, because system. String is non-mutable, it doesn't matter even if it points to the same object.
// And the string pool is used in. Net to maintain
If (OBJ = NULL | obj. GetType () = typeof (string ))
Return OBJ;
Object newobj = NULL;
Try
{
// Try to call the default constructor
Newobj = activator. createinstance (obj. GetType ());
}
Catch
{
// If it fails, you have to enumerate the constructor.
Foreach (constructorinfo Ci in OBJ. GetType (). getconstructors (bindingflags. instance | bindingflags. Public | bindingflags. nonpublic ))
{
Try
{
Parameterinfo [] Pis = CI. getparameters ();
Object [] objs = new object [PIs. Length];
For (INT I = 0; I <PIs. length; I ++)
{
If (PIS [I]. parametertype. isvaluetype)
Objs [I] = activator. createinstance (PIS [I]. parametertype );
Else
// The parameter type may be an abstract class or interface, which is difficult to instantiate
// All I can think of is to enumerate the assembly in the application domain and find the class that implements the abstract class or interface.
// But it is obviously too complicated
Objs [I] = NULL;
}
Newobj = CI. Invoke (objs );
// No matter which constructor is called, you only need to succeed.
Break;
}
Catch
{
}
}
}
Foreach (fieldinfo fi in obj. GetType (). getfields (bindingflags. Public | bindingflags. nonpublic | bindingflags. instance ))
{
If (Fi. fieldtype. isvaluetype | fi. fieldtype = typeof (string ))
Fi. setvalue (newobj, Fi. getvalue (OBJ ));
Else
Fi. setvalue (newobj, deepcloneobject (Fi. getvalue (OBJ )));
}
// The Private instance field of the base class cannot be found in the subclass, but it still occupies the memory space of the subclass object
Deep (newobj, OBJ );
Return (t) newobj;
}

// Clone the private instance field on the inheritance tree
Public void deep (Object newobj, object OBJ)
{
For (type father = newobj. GetType (). basetype; father! = Typeof (object); father = Father. basetype)
{
Foreach (fieldinfo fi in Father. getfields (bindingflags. nonpublic | bindingflags. instance ))
{
// Only private fields need to be processed, because non-private members have already processed the fields in the subclass.
If (Fi. isprivate)
{
If (Fi. fieldtype. isvaluetype | fi. fieldtype = typeof (string ))
{
Fi. setvalue (newobj, Fi. getvalue (OBJ ));
}
Else
{
Fi. setvalue (newobj, deepcloneobject (Fi. getvalue (OBJ )));
}
}
}
}
}
}

 

 

Write a code to test it:

 

Class Program
{
Static void main ()
{
Data3 data3 = new data3 ();
Data DATA = new data (data3 );
Data. privalue = "pri ";
Data. Integer = 3;

// The clonedata object is modified, but the data object is not affected. The clone is successful.
Cstod CTD = new cstod ();
Data clonedata = CTD. deepcloneobject (data );
Clonedata. Integer = 1000;
Clonedata. privalue = "clone ";
Clonedata. value. d3string = "clonestr ";
Console. writeline (data. Integer + "<->" + clonedata. integer );
Console. writeline (data. privalue + "<->" + clonedata. privalue );
Console. writeline (data. value. d3string + "<->" + clonedata. value. d3string );

// If the refdata object is modified, the data object is also changed, indicating that it is the same object.
Data refdata = data;
Refdata. Integer = 555;
Refdata. privalue = "Ref ";
Refdata. value. d3string = "refstr ";
Console. writeline (data. Integer + "<->" + refdata. integer );
Console. writeline (data. privalue + "<->" + refdata. privalue );
Console. writeline (data. value. d3string + "<->" + refdata. value. d3string );
}
}
Class data: data2
{
Public Data (data3 value)
{
This. value = value;
}
Public Data (){}
Public data3 value;

}
Class data2
{
Public data2 (INT value)
{
This. Integer = value;
}
Public String privalue
{
Get
{
Return privalue;
}
Set
{
Privalue = value;
}
}
Public data2 (){}
Public int integer;
Private string privalue;
}
Class data3
{
Public data3 ()
{
D3string = "D3 ";
D3integer = 3;
}
Public String d3string;
Private int d3integer;
}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.