Я использую отражение для копирования объекта любого пользовательского класса во время выполнения. Я использую FieldInfo
, чтобы получить все поля и затем правильно скопировать их в зависимости от их типа.
Единственный тип, с которым я могу работать в начале алгоритма копирования, это System.Object
(AKA object
),Я делаю много проверок типов. Поэтому, когда мой метод проверки говорит, что этот конкретный объект является неким простым одномерным массивом, это, несомненно, массив. Однако я могу получить доступ к типу элементов в этом массиве только во время выполнения.
Я успешно скопировал List<type known at runtime>
следующим образом:
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;
}
Затем я попытался переписать метод дляпростой массив:
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;
}
Но это возвращает исключение при присваивании значения полю с использованием 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[]'.'
Для этого конкретного примера массив выглядел так:
public int[] Array = { 1, 2, 3 };
И последнее: я знаю, как решить эту проблему, используя универсальные методы, и MethodInfo ...MakeGenericMethod(...).Invoke
, я просто подумал, что этого можно избежать (возможно, я ошибаюсь). Также сериализация не может быть использована.