2017-02-22 4 views
0

Я использую класс ниже для того, чтобы сделать глубокое клонирование без сериализации.Глубокое клонирование коллекций (пара ключей/значений) с использованием Reflection

public class AbstractClone 
{ 

    public AbstractClone Clone() 
    { 
     Type typeSource = this.GetType(); 
     AbstractClone tObject = (AbstractClone)FormatterServices.GetUninitializedObject(typeSource); 

     PropertyInfo[] propertyInfo = typeSource.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 

     foreach (PropertyInfo property in propertyInfo) 
     { 
      if (property.CanWrite) 
      { 

       if (property.PropertyType.IsValueType || property.PropertyType.IsEnum || property.PropertyType.Equals(typeof(System.String))) 
       { 
        property.SetValue(tObject, property.GetValue(this, null), null); 
       } 
       else 
       { 
        object objPropertyValue = property.GetValue(this, null); 

        if (objPropertyValue == null) 
        { 
         property.SetValue(tObject, null, null); 
        } 
        else 
        { 
         property.SetValue(tObject, ((AbstractClone)objPropertyValue).Clone(), null); 
        } 
       } 
      } 

     } 
     return tObject; 
    } 
} 

Я наследую все классы из этого, которые нужно клонировать.

Это прекрасно работает со всеми объектами, за исключением ключевых пар значений или коллекций, таких как SortedList, словарь и т.д.

Может кто-нибудь предложить способ клонировать KeyValue пары, как SortedList Словаря.

ответ

0

Глубокое копирование является серьезной задачей. Во-первых, ваше решение, возможно, просто невозможно использовать, поскольку оно требует наследования от вашего типа, и вы не можете наследовать сторонние классы. Вторая проблема заключается в том, что это не по-настоящему глубоко: вы будете копировать все ссылки:

class Employee 
{ 
    public string Name {get; set;} 
    public Position Position {get; set;} 
} 
class Position 
{ 
    public string Name {get;set;} 
    public int ID {get;set;} 
} 

Если изменить Name свойства Position недвижимости в исходном объекте, вы увидите эти изменения в вашей копии. И если вы попытаетесь обновить свое решение для рекурсивного выполнения свойств, вам придется иметь дело с ссылками на циклы.

Однако эта работа уже выполнена, и вам просто нужно искать готовое решение, например, this one.

Смежные вопросы