使用反射深度克隆集合(键/值对)

时间:2017-02-22 15:28:52

标签: c# reflection cloning

我在下面的课程中使用深度克隆进行序列化。

  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,Dictionary等

之类的集合之外,这适用于所有对象

有没有人可以建议克隆KeyValue对的方法,比如SortedList of Dictionary。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

由于您已在此处强制执行继承规则,因此只会对从AbstractClone派生的类进行深度克隆,您可以在其上添加[Serializable]并取消强制继承。序列化,然后是反序列化是一种有保证的深度克隆技术。

p -> p+e