Hello,
I have two C# classes. Right now, both are the same, but later one might have some members the other has not...
I want to copy my class source to my class target but dynamically.
I wrote a void to do so.
It can already step through the sub-classes, but I don't know how to pass them, I only get the type/declaration with my void. Any help / idea please?
My code here:
void copyObject(object source, object target)
{
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 );
FieldInfo[] fiftarget = target.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public );
for (int i = 0; i < fifsource.Length; i++)
{
if (fifsource.GetType() == fiftarget.GetType())
{
if (i < fiftarget.Length)
{
copyObject(fifsource.GetValue(i), fiftarget.GetValue(i));
}
}
}
}
}
Thanks a lot!
Eric
I changed my code, now I runs through but the target is still empty after that:
The single strings and ints now are copied to target, but target lost its sense somehow when I am doing like this,
and afterwards my target is empty...
<pre lang="cs">void copyObject(object source, object target)
{
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);
FieldInfo[] fiftarget = target.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);
for (int i = 0; i < fifsource.Length; i++)
{
if (fifsource.GetType() == fiftarget.GetType())
{
if (i < fiftarget.Length)
{
object psource = source.GetType().GetFields()[i].GetValue(source);
object ptarget = target.GetType().GetFields()[i].GetValue(target);
if (ptarget == null && psource.GetType() == (typeof(string)))
{
ptarget = string.Empty;
}
copyObject(psource, ptarget);
}
}
}
}
}
}
Hello again, sorry to disturb again. I improved my solution but it is still not working.
I am using ref now so I don't lose the reference of the objects.
I only have problems when setting the found values now.
Two pieces of code now, the first has some comments, this seemed to work but after that
the target class was still empty (I guess the way I tried again the objects lose their reference).
So I decided to add a new function copySubObject
to set the values, but I have problems setting them into the right place...
I believe this can be done...please help me out.
I need to do this or a similar way, it is not my decision.
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);
FieldInfo[] fiftarget = target.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);
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()[i];
object ptarget = target.GetType().GetFields()[i];
object vsource = source.GetType().GetFields()[i].GetValue(source);
object vtarget = target.GetType().GetFields()[i].GetValue(target);
refcopyObject(ref psource, ref ptarget, vsource, vtarget);
}
}
}
}
else
{
copySubObject(ref source, ref target, svalue, tvalue);
}
}
}
}
The new routine gets the references and the values (which are structs or lists)
void copySubObject(ref object source, ref object target, object svalue, object tvalue)
{
if (source != null && target != null)
{
FieldInfo[] fifs = svalue.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);
if (fifs.Length > 0)
{
FieldInfo[] fift = tvalue.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);
for (int i = 0; i < fifs.Length; i++)
{
if (fifs.GetType() == fift.GetType())
{
if (i < fift.Length)
{
object psource = svalue.GetType().GetFields()[i].GetValue(svalue);
object ptarget = tvalue.GetType().GetFields()[i].GetValue(tvalue);
if (ptarget == null)
{
if (psource.GetType() == (typeof(string)))
{
target.GetType().GetFields()[i].SetValue(tvalue, psource);
}
if (psource.GetType() == (typeof(int)))
{
target.GetType().GetFields()[i].SetValue(tvalue, psource);
}
}
}
}
}
}
}
}