0

I have a class. I have no influence on thios class, it is coming from somewhere else, from a 3rd party.

I have my own class. When I update it is the same. But it might have missing objects later.

I need to copy Class lets calls it here "source" to my class "target".

source has structs, lists with ints and strings.

First I tried to get down trough it without Reference, it looked like it worked, but the target was empty after that because of the missing reference.

(if anybody wants to see that code let me know).

Now I made a 2nd attempt now: I am not sure if it is the right way, I am having problems copying the values to the right place in the target,

stepping through the class works. Please help me out I need an urgent solution. And please with copying Class existing source to existing target (if the items exisits there in the same struct),

please no suggestions to it totally different because I have no influence on Class source, and Class Target itself, I just need to copy values and subclasses.

Here my code so far. Working through class and subclasses works, have problems setting the values (to the right place):

void refcopyObject(ref object source,ref object target,object svalue,object tvalue) 
{ 
if (source != null && target != null) 
{ 
if (source.GetType() == (typeof(string))) 
{ 
target = source; 
} 
else 
if (source.GetType() == (typeof(int))) 
{ 
target = source; 
} 
else 
if (source.GetType() == (typeof(IntPtr))) 
{ 
target = source; 
} 
else 
{ 
FieldInfo[] fifsource = source.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); // | BindingFlags.NonPublic 
FieldInfo[] fiftarget = target.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); // | BindingFlags.NonPublic 
if (fifsource.Length > 0) 
{ 
for (int i = 0; i < fifsource.Length; i++) 
{ 
if (fifsource.GetType() == fiftarget.GetType()) 
{ 
if (i < fiftarget.Length) 
{ 
object psource = source.GetType().GetFields(); 
object ptarget = target.GetType().GetFields(); 
object vsource = source.GetType().GetFields().GetValue(source); 
object vtarget = target.GetType().GetFields().GetValue(target); 
refcopyObject(ref psource, ref ptarget, vsource, vtarget); 
} 
} 
} 
} 
else 
{ 
//Unten angekommen 
copySubObject(ref source, ref target, svalue, tvalue); 
////So gehts nicht, dann wird die Referenz wieder verloren 
//FieldInfo[] fifs = svalue.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); // | BindingFlags.NonPublic 
//if (fifs.Length > 0) 
//{ 
// FieldInfo[] fift = tvalue.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); // | BindingFlags.NonPublic 
// for (int i = 0; i < fifs.Length; i++) 
// { 
// if (fifs.GetType() == fift.GetType()) 
// { 
// if (i < fift.Length) 
// { 
// object psource = svalue.GetType().GetFields().GetValue(svalue); 
// object ptarget = tvalue.GetType().GetFields().GetValue(tvalue); 
// if (ptarget == null) 
// { 
// //Ganz unten angekommen, Problem bei Listen 
// if (psource.GetType() == (typeof(string))) 
// { 
// tvalue.GetType().GetFields().SetValue(tvalue,psource); 
// } 
// if (psource.GetType() == (typeof(int))) 
// { 
// tvalue.GetType().GetFields().SetValue(tvalue, psource); 
// } 
// } 
// else 
// { 
// refcopyObject(ref psource, ref ptarget, null, null); 
// } 
// } 
// } 
// } 
//} 
} 
} 
} 
}

I guess the problems start where the comments start. I got to a struct or list at that part, which contain strings or int...

Thanks a lot!

Quick Reply

user739611
  • 21
  • 2
  • You don't need all those `ref`s. You do need some spaces. – H H May 05 '11 at 13:18
  • Similar question: [How do you do a deep copy an object in .Net (C# specifically)?](http://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-an-object-in-net-c-specifically) – Devendra D. Chavan May 05 '11 at 13:27

1 Answers1

1

Well, the simplest way to get a deep copy of a serializable object is to serialize it to a MemoryStream, and then deserialize it back to a new object:

public static T DeepCopy<T>(T other)
{
   using (MemoryStream ms = new MemoryStream())
   {
       BinaryFormatter formatter = new BinaryFormatter();
       formatter.Serialize(ms, other);
       ms.Position = 0;
       return (T)formatter.Deserialize(ms);
   }
}

Note that this requires your source type to be marked with the [Serializable] attribute, and since you don't have access to that code, it doesn't depend on you:

[Serializable]
public class MyClass 
{
     ...
}

Non-serializable classes

There are some solutions which use Reflection to get a deep copy (like CodeProject: Deep copy of objects in C#), although it's important to test if they handle circular references properly. If your object doesn't reference itself (directly or indirectly), you may try this approach.

vgru
  • 49,838
  • 16
  • 120
  • 201
  • Like I said I have no influence on the source class. – user739611 May 05 '11 at 13:42
  • I really have an existing class source and an existing class target. I need to copy everything I find from source to target. I cannot work with cloning etc or change one of the classes itself... – user739611 May 05 '11 at 13:43
  • @user739611: Try the deep copy method from the [CodeProject article](http://www.codeproject.com/KB/cs/Deep_copy_of_objects.aspx). If there are no circular references in your object graph, it should work. – vgru May 05 '11 at 13:46
  • Hello, the problem: this always creates a new object. It creates the subclasses etc. Like cloning does. When I have a subclass in source but not in target, it adds this subclass. If I remove those adds it won't work with those setvalues anymore because classes won't match anymore (I have my classes with the same structure and als same names but different namespaces)... – user739611 May 05 '11 at 14:28
  • @user739611: In that case you might try [AutoMapper](http://automapper.codeplex.com/). It's a library for custom object-to-object mapping, which does a lot of work by convention (as little configuration as needed). – vgru May 05 '11 at 21:36