原文路径:https://blog.csdn.net/qq_28839293/article/details/79487294
1、浅复制:
class Program
{
public static void Main(string[] args)
{
var classA1 = new ClassA
{
a = 1,
b = "haha",
d = new ClassB{ c ="haha" }
};
var classA2 = (ClassA)classA1.Clone();
classA2.b = "xixi";
classA2.d.c = "xixi";
Console.WriteLine("classA1.b=" + classA1.b + "\nclassA2.b=" + classA2.b);
Console.WriteLine("classA1.d.c=" + classA1.d.c + "\nclassA2.d.c=" + classA2.d.c);
}
}
public class ClassA : ICloneable
{
public int a;
public string b;
public ClassB d;
public object Clone()
{
object obj = new ClassA();
//字段
FieldInfo[] fields = typeof(ClassA).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
for (int i = 0; i < fields.Length; i++)
{
FieldInfo field = fields[i];
field.SetValue(obj, field.GetValue(this));
}
//属性
PropertyInfo[] properties = typeof(ClassA).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
for (int i = 0; i < properties.Length; i++)
{
PropertyInfo property = properties[i];
property.SetValue(obj, property.GetValue(this));
}
return obj;
}
}
public class ClassB
{
public string c;
}
2、深度复制:使用反射进行深复制时,若碰到字段或属性为引用类型,则需要递归调用
public static object DeepClone(Object obj)
{
Type type = obj.GetType();
//对于没有公共无参构造函数的类型此处会报错
object returnObj = Activator.CreateInstance(type);
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
for (int i = 0; i < fields.Length; i++)
{
FieldInfo field = fields[i];
var fieldValue = field.GetValue(obj);
///值类型,字符串,枚举类型直接把值复制,不存在浅拷贝
if (fieldValue.GetType().IsValueType || fieldValue.GetType().Equals(typeof(System.String)) || fieldValue.GetType().IsEnum)
{
field.SetValue(returnObj, fieldValue);
}
else
{
field.SetValue(returnObj, DeepClone(fieldValue));
}
}
//属性
PropertyInfo[] properties = typeof(ClassA).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
for (int i = 0; i < properties.Length; i++)
{
PropertyInfo property = properties[i];
var propertyValue = property.GetValue(obj);
if (propertyValue.GetType().IsValueType || propertyValue.GetType().Equals(typeof(System.String)) || propertyValue.GetType().IsEnum)
{
property.SetValue(returnObj, propertyValue);
}
else
{
property.SetValue(returnObj, DeepClone(propertyValue));
}
}
return returnObj;
}
1.这里我没再使用ICloneable中的clone方法,而是单独写了一个静态方法来实现(因为涉及到递归)
2.对于没有公共无参构造函数的类型,该方法不适用,代码中也做了注解
3.对于浅复制与深复制这类操作,最好是写成工具类的形式,而不是去修改原有的类