I am using reflection to copy an object of any custom class at runtime. I am using FieldInfo
to get all the fields and then properly copy them based on their type.
Only type I can work with at the start of the copy algorithm is System.Object
(AKA object
). I do a lot of type checking. So when my check method says this particular object is some simple one-dimensional array, it is array, no doubt. However I can access the type of elements in that array only at runtime.
I did successfully copied List<type known at runtime>
like this:
public object Get_ListCopy(object original)
{
Type elementType = original.GetType().GetGenericArguments()[0];
Type listType = typeof(List<>).MakeGenericType(elementType);
object copy = Activator.CreateInstance(listType);
var copyIList = copy as IList;
foreach (var item in original as IEnumerable)
copyIList.Add(item);
copy = copyIList;
return copy;
}
Then I tried to re-write the method for simple array:
public object Get_ArrayCopy(object original)
{
Type elementType = original.GetType().GetElementType(); // difference here
Type listType = typeof(List<>).MakeGenericType(elementType);
object copy = Activator.CreateInstance(listType);
var copyIList = copy as IList;
foreach (var item in original as IEnumerable)
copyIList.Add(item);
copy = Enumerable.Range(0, copyIList.Count).Select(i => copyIList[i]).ToArray(); // difference here
return copy;
}
But that returns an exception when assigning value to field using FieldInfo.SetValue(copyObject, convertedValue) // where convertedValue is object copy from the method above
:
System.ArgumentException: 'Object of type 'System.Object[]' cannot be converted to type 'System.Int32[]'.'
For that particular example the array looked like this:
public int[] Array = { 1, 2, 3 };
One last thing: I know how to solve this problem using generic methods and MethodInfo ...MakeGenericMethod(...).Invoke
, I just thought it could be avoided(maybe I am wrong). Also serialization can't be used.
Aucun commentaire:
Enregistrer un commentaire