.NET中对于复杂对象制作副本比较困难,闲暇之时写了这个方法,和大家分享。
本案例用于大型对象的副本制作,常见的应用场景就是树形对象节点的拷贝,但是也有局限性,目前使用于类里有基本类型(int stirng float 等)的属性和泛型属性的拷贝,其他的拷贝暂时不支持。
1、自定Teacher类
class Teacher { public Teacher() { } /// <summary> /// 老师姓名 /// </summary> public string TeacherName { get; set; } /// <summary> /// 老师的工号 /// </summary> public string TeacherNumber { get; set; } /// <summary> /// 学生列表 /// </summary> public List<Student> lists { get; set; } }
2、学生类型定义
class Student { /// <summary> /// 学生姓名 /// </summary> public string StudentName { get; set; } public Student() { } }
3、声明并初始化变量
Teacher teacher = new Teacher() { TeacherNumber = "0000000001", TeacherName = "老师1", lists = new List<Student> { new Student { StudentName = "学生1" }, new Student { StudentName = "学生2" } } };
4、 对象进行副本的制造
Teacher teacherAfter = teacher.Copy();
5、Copy方法的实现
1 #region 对类进行深度拷贝 2 /// <summary> 3 /// 对类进行深度拷贝 4 /// </summary> 5 /// <typeparam name="T"></typeparam> 6 /// <param name="o"></param> 7 /// <returns></returns> 8 public static T Copy<T>(this T o) 9 { 10 Assembly assembly = Assembly.GetExecutingAssembly(); 11 Type t = o.GetType(); 12 T t1 = (T)assembly.CreateInstance(t.FullName); 13 14 PropertyInfo[] PropertyInfos = t.GetProperties(); 15 16 foreach (PropertyInfo propertyInfo in PropertyInfos) 17 { 18 string PropertyName = propertyInfo.Name; 19 var propertyValue = propertyInfo.GetValue(o, null); 20 if (propertyValue is IEnumerable<object>) 21 { 22 IEnumerable<object> propertyList = propertyValue as IEnumerable<object>; 23 object list = Activator.CreateInstance(propertyValue.GetType()); 24 foreach (var item in propertyList) 25 { 26 var method = list.GetType().GetMethod("Add"); 27 method.Invoke(list, new[] { Copy<object>(item) }); 28 } 29 propertyInfo.SetValue(t1, list, null); 30 } 31 else 32 { 33 propertyInfo.SetValue(t1, propertyValue, null); 34 } 35 } 36 return t1; 37 } 38 #endregion
代码讲解
1、首先这是个拓展方法,拓展方法不懂得百度去。
2、 10行、11行、12行用于实现一个类型的实例化t1。
3、通过遍历o的属性对拷贝对象t1进行赋值,这是针对基本类型的属性而言,对于IEnumerable就涉及到类型转换,然后进行遍历,递归调用Copy方法。
提供demo的下载地址 下载