Use reflection to copy a class

T

Torben Laursen

I have a complicated class that I use to store a lot of values
Now I need a copy of that class and I have been trying to find a way to do
this automatic so I don't have to assign all properties and classes by hand
(about 200 properties).
I found this post on google:
http://www.thescripts.com/forum/thread225825.html
But how does this code work and what do I use instead of "oth" in the last
line
using System.Reflection;
class MyClass {
int a;
// lots of different fields goes here
float x;
MyClass() {
// default constructor
}
MyClass (MyClass my) {
// create an exact copy of mc here
FieldInfo[] fields = typeof(MyClass).GetFields(BindingFlags.Public
| BindingFlags.NonPublic | BindingFlags.Instance);
foreach(FieldInfo f in fields) {
f.SetValue(this,f.GetValue(oth));
}
}
}

Thansk Torben
 
D

DeveloperX

I have a complicated class that I use to store a lot of values
Now I need a copy of that class and I have been trying to find a way to do
this automatic so I don't have to assign all properties and classes by hand
(about 200 properties).
I found this post on google:http://www.thescripts.com/forum/thread225825.html
But how does this code work and what do I use instead of "oth" in the last
line
using System.Reflection;
class MyClass {
int a;
// lots of different fields goes here
float x;
MyClass() {
// default constructor}

MyClass (MyClass my) {
// create an exact copy of mc here
FieldInfo[] fields = typeof(MyClass).GetFields(BindingFlags.Public
| BindingFlags.NonPublic | BindingFlags.Instance);
foreach(FieldInfo f in fields) {
f.SetValue(this,f.GetValue(oth));

}
}
}

Thansk Torben

All it's doing is iterating through the fields, so GetValue's
parameter is the object we're copying. However, this method won't work
with a derived type.

so if you have

public class Test
{
private int f;
public int F
{
get
{
return f;
}
set
{
f=value;
}
}
}

public class Test2 : Test
{
private int g;
public int G

{
get
{
return g;
}
set
{
g=value;
}
}
}

public Test2 Clone2(Test2 pTest2)
{
Test2 o = new Test2();

FieldInfo[] fields = typeof(Test2).GetFields(BindingFlags.Public
| BindingFlags.NonPublic | BindingFlags.Instance);
foreach(FieldInfo f in fields)
{
f.SetValue(o,f.GetValue(pTest2));
}
return o;
}

Cloning a Test2 with his code (mashed up above) will result in g being
set but not f. The following seems to work, but I've not extensively
tested it, so consider it a starting point rather than a solution.
Apologies for the scrappyness of the code :)

public Test2 Clone3(Test2 pTest2)
{
Test2 o = new Test2();
Type t;
FieldInfo[] fields;
t = typeof(Test2).BaseType;
while(t != null)
{
fields = t.GetFields(BindingFlags.Public
| BindingFlags.NonPublic | BindingFlags.Instance);
foreach(FieldInfo f in fields)
{
f.SetValue(o,f.GetValue(pTest2));
}
t = t.BaseType;
}

fields = typeof(Test2).GetFields(BindingFlags.Public
| BindingFlags.NonPublic | BindingFlags.Instance);
foreach(FieldInfo f in fields)
{
f.SetValue(o,f.GetValue(pTest2));
}
return o;
}
 
A

Alberto Poblacion

Torben Laursen said:
But how does this code work and what do I use instead of "oth" in the last
line
[...]
f.SetValue(this,f.GetValue(oth));

How does it work? You are iterating through all the fields in the class,
reading the values from another instance ("oth") and inserting the values in
your current instance, which will give you a shallow copy of the object,
which is what you wanted in the first place.
What do you use instead of "oth"? Well, the object that you wanted to
copy in the first place, which was the purpose of the whole thing, wasn't
it? I believe that there is an error in the parameters of the constructor.
Where you write MyClass(MyClass my), you should have MyClass(MyClass oth),
so you can pass the object to copy as an argument when you do a "new
MyClass".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top