Say I have this class Myclass that contains this method:
public class MyClass
{
public int MyProperty { get; set; }
public int MySecondProperty { get; set; }
public MyOtherClass subClass { get; set; }
public object clone<T>(object original, T emptyObj)
{
FieldInfo[] fis = this.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
object tempMyClass = Activator.CreateInstance(typeof(T));
foreach (FieldInfo fi in fis)
{
if (fi.FieldType.Namespace != original.GetType().Namespace)
fi.SetValue(tempMyClass, fi.GetValue(original));
else
fi.SetValue(tempMyClass, this.clone(fi.GetValue(original), fi.GetValue(original)));
}
return tempMyClass;
}
}
Then this class:
public class MyOtherClass
{
public int MyProperty777 { get; set; }
}
when I do this:
MyClass a = new MyClass {
MyProperty = 1,
MySecondProperty = 2,
subClass = new MyOtherClass() { MyProperty777 = -1 }
};
MyClass b = a.clone(a, a) as MyClass;
how come on the second call to clone, T is of type object and not of type MyOtherClass
Your second (recursive) call to clone
passes the result of GetValue
as the second argument, which is of type object
, and hence T
is object
.
i.e.
fi.SetValue(tempMyClass, this.clone(fi.GetValue(original), fi.GetValue(original)));
The result of GetValue
on a FieldInfo
is an object
.
Given that you pass the same thing twice in all cases, the design of the clone
method is possibly wrong. You probably don't need generics there. Just use obj.GetType()
to get the type information of the second argument (if indeed you really need a second argument).
It would make more sense to constrain the return type using generics, so that the cast isn't necessary on the calling side. Also you could make Clone into an extension method so it could apply to anything.
On the other hand, the thing you're trying to do (an automatic deep clone) is unlikely to be generally useful. Most classes end up hold references to things that they don't own, so if you clone such an object, you end up accidentally cloning half of your application framework.