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);