标签:修改 浅复制 inf 一个 details 递归调用 类型 bind lse
原文路径: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.对于浅复制与深复制这类操作,最好是写成工具类的形式,而不是去修改原有的类
标签:修改 浅复制 inf 一个 details 递归调用 类型 bind lse
原文地址:https://www.cnblogs.com/MartinSun123/p/9345649.html