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

C# 使用反射深度克隆集合(键/值对),c#,reflection,cloning,C#,Reflection,Cloning,我正在使用下面的类进行深度克隆,而不进行序列化 public class AbstractClone { public AbstractClone Clone() { Type typeSource = this.GetType(); AbstractClone tObject = (AbstractClone)FormatterServices.GetUninitializedObject(typeSource); Pro

我正在使用下面的类进行深度克隆,而不进行序列化

  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等)之外的所有对象


有谁能建议一种克隆键值对的方法,比如字典的SortedList。

深度复制是一项严肃的任务。首先,您的解决方案可能根本无法使用,因为它需要从您的类型继承,并且您不能继承第三方类。第二个问题是它不是真正深入的:您将复制所有引用:

class Employee
{
  public string Name {get; set;}
  public Position Position {get; set;}
}
class Position
{
  public string Name {get;set;}
  public int ID {get;set;}
}
如果更改原始对象中
位置
属性的
名称
属性,您将在副本中看到这些更改。 如果您试图升级解决方案以递归方式运行属性,则必须处理循环引用


然而,这项工作已经完成,您只需寻找一个现成的解决方案,例如,。

深度复制是一项严肃的任务。首先,您的解决方案可能根本无法使用,因为它需要从您的类型继承,并且您不能继承第三方类。第二个问题是它不是真正深入的:您将复制所有引用:

class Employee
{
  public string Name {get; set;}
  public Position Position {get; set;}
}
class Position
{
  public string Name {get;set;}
  public int ID {get;set;}
}
如果更改原始对象中
位置
属性的
名称
属性,您将在副本中看到这些更改。 如果您试图升级解决方案以递归方式运行属性,则必须处理循环引用


然而,这项工作已经完成,您只需要寻找一个现成的解决方案,例如。

因为您已经在这里强制执行继承规则,只有从AbstractClone派生的类才会被深度克隆,您可以在其上粘贴一个[Serializable],并放弃强制执行继承。序列化,然后反序列化是一种有保证的深度克隆技术

[Serializable]
class T
{
    public int F1 { get; set; }
    public int F2 { get; set; }
}

T CloneT(T obj)
{
    var ms = new MemoryStream();

    var formatter = new BinaryFormatter();
    formatter.Serialize(ms, o);

    ms.Position = 0;

    var clone = (T)formatter.Deserialize(ms);

    return clone;
}

var o = new T { F1 = 5, F2 = 12 };
CloneT(o);

因为您已经在这里强制执行继承规则,所以只有从AbstractClone派生的类才会被深度克隆,所以您可以在其上粘贴一个[Serializable],并放弃强制执行继承。序列化,然后反序列化是一种有保证的深度克隆技术

[Serializable]
class T
{
    public int F1 { get; set; }
    public int F2 { get; set; }
}

T CloneT(T obj)
{
    var ms = new MemoryStream();

    var formatter = new BinaryFormatter();
    formatter.Serialize(ms, o);

    ms.Position = 0;

    var clone = (T)formatter.Deserialize(ms);

    return clone;
}

var o = new T { F1 = 5, F2 = 12 };
CloneT(o);