對象的深拷貝--反射

繼續上節的對象深拷貝,上節講了經過序列化和反序列化來實現深度拷貝,這一節咱們來說述一下第二種深度拷貝的方法,反射。經過反射來實現深度拷貝。this

反射主要是在運行時獲取對象的元信息,System.Reflection命名空間容許咱們在程序運行時來獲取對象的信息、建立已存在類的實例,也可以獲取對象的屬性和執行對象的方法。spa

下面我建立一個靜態的方法來接收任何類型的對象,並返回一個新對象的引用。code

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Reflection;
 6 
 7 namespace ReflectionCopy
 8 {
 9     public class Utility
10     {
11         public static object CloneObject(object objsource)
12         {
13             //第一步獲取原對象的類型,並建立一個同類型的對象
14             Type typesource = objsource.GetType();
15 
16             object objTarget = Activator.CreateInstance(typesource);
17 
18             //第二步獲取原對象的全部屬性
19 
20             PropertyInfo[] propertyinfo = typesource.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
21 
22             //第三步將原對象的全部屬性賦給目標對象
23 
24             foreach (PropertyInfo item in propertyinfo)
25             {
26                 if (item.CanWrite)
27                 {
28 
29                     //值類型,字符串,枚舉類型直接把值複製,不存在淺拷貝  雖然字符串是引用類型,可是字符串是不可變的,每次都是建立新的字符串對象,因此不存在淺拷貝
30                     if (item.PropertyType.IsEnum || item.PropertyType.IsValueType || item.PropertyType.Equals(typeof(System.String)))
31                     {
32 
33                         item.SetValue(objTarget, item.GetValue(objsource, null), null);
34                     }
35                     else
36                     {
37                         object objpropertyvalue = item.GetValue(objsource, null);
38 
39                         item.SetValue(objTarget, CloneObject(objpropertyvalue), null);
40                     }
41                 }
42             }
43             return objTarget;
44         }
45     }
46 }

這個方法也能夠作成一個擴展方法:對象

 1 public static class ObjectExtension
 2 {
 3     public static object CloneObject(this object objSource)
 4     {
 5         //Get the type of source object and create a new instance of that type
 6         Type typeSource = objSource.GetType();
 7         object objTarget = Activator.CreateInstance(typeSource);
 8  
 9         //Get all the properties of source object type
10         PropertyInfo[] propertyInfo = typeSource.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
11  
12         //Assign all source property to taget object 's properties
13         foreach (PropertyInfo property in propertyInfo)
14         {
15             //Check whether property can be written to
16             if (property.CanWrite)
17             {
18                 //check whether property type is value type, enum or string type
19                 if (property.PropertyType.IsValueType || property.PropertyType.IsEnum || property.PropertyType.Equals(typeof(System.String)))
20                 {
21                     property.SetValue(objTarget, property.GetValue(objSource, null), null);
22                 }
23                 //else property type is object/complex types, so need to recursively call this method until the end of the tree is reached
24                 else
25                 {
26                     object objPropertyValue = property.GetValue(objSource, null);
27                     if (objPropertyValue == null)
28                     {
29                         property.SetValue(objTarget, null, null);
30                     }
31                     else
32                     {
33                         property.SetValue(objTarget, objPropertyValue.CloneObject(), null);
34                     }
35                 }
36             }
37         }
38         return objTarget;
39     }
40 }

如今咱們調用該方法,看看結果:blog

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace ReflectionCopy
 7 {
 8     class Program
 9     {
10         static void Main(string[] args)
11         {
12             Employee emp = new Employee();
13 
14             emp.EmployeeId = 1000;
15             emp.EmployeeName = "IT少年";
16             emp.Department = new Department { DepartmentId = 1, DepartmentName = "Examination" };
17 
18             Employee empclone = emp.CloneObject() as Employee;
19 
20             emp.EmployeeId = 1003;
21             emp.EmployeeName = "TTT";
22             emp.Department.DepartmentId = 3;
23             emp.Department.DepartmentName = "admin";
24             Console.WriteLine("----emp原始對象------");
25             Console.WriteLine("拷貝前DepartmentName應該是admin:  " + emp.Department.DepartmentName);
26             Console.WriteLine("拷貝前DepartmentID應該是3:  " + emp.Department.DepartmentId);
27 
28             Console.WriteLine("----empclone拷貝對象------");
29             Console.WriteLine("拷貝DepartmentName應該是Examination:    " + empclone.Department.DepartmentName);
30             Console.WriteLine("拷貝DepartmentID應該是1:     " + empclone.Department.DepartmentId);
31             Console.ReadKey();
32         }
33 
34     }
35 }

運行結果能夠看出和序列化和反序列化深拷貝同樣的。字符串

相關文章
相關標籤/搜索