在開發過程中,我們會遇到這樣一個問題,編輯了一個對象之後,我們想要把這個對象修改了哪些內容保存下來,以便將來查看和追責。 首先我們要創建一個User類 然後在Main函數中聲明並初始化一個User對象 因為要對比對象編輯前後的內容,所以需要備份一下這個UserA,我們來個深拷貝 接下來的工作是修改U ...
在開發過程中,我們會遇到這樣一個問題,編輯了一個對象之後,我們想要把這個對象修改了哪些內容保存下來,以便將來查看和追責。
首先我們要創建一個User類
1 public class User 2 { 3 private string name; 4 public string Name 5 { 6 get { return name; } 7 set { name = value; } 8 } 9 private string age; 10 public string Age 11 { 12 get { return age; } 13 set { age = value; } 14 } 15 private string sex; 16 public string Sex 17 { 18 get { return sex; } 19 set { sex = value; } 20 } 21 }
然後在Main函數中聲明並初始化一個User對象
1 User userA = new User() 2 { 3 Name = "李四", 4 Age = "25", 5 Sex = "男", 6 };
因為要對比對象編輯前後的內容,所以需要備份一下這個UserA,我們來個深拷貝
1 User userB = DeepCopyByXml<User>(userA);
1 /// <summary> 2 /// 深拷貝 3 /// </summary> 4 /// <typeparam name="T"></typeparam> 5 /// <param name="obj"></param> 6 /// <returns></returns> 7 public static T DeepCopyByXml<T>(T obj) where T : class 8 { 9 object retval; 10 using (MemoryStream ms = new MemoryStream()) 11 { 12 XmlSerializer xml = new XmlSerializer(typeof(T)); 13 xml.Serialize(ms, obj); 14 ms.Seek(0, SeekOrigin.Begin); 15 retval = xml.Deserialize(ms); 16 ms.Close(); 17 } 18 return (T)retval; 19 }
接下來的工作是修改UserA的屬性,然後和UserB對比,利用反射來實現該功能
/// <summary> /// Model對比 /// </summary> /// <typeparam Name="T"></typeparam> /// <param Name="oldModel"></param> /// <param Name="newModel"></param> private static void CompareModel<T>(T oldModel, T newModel) where T : class { string changeStr = string.Empty; PropertyInfo[] properties = oldModel.GetType().GetProperties(); Console.WriteLine("--------用戶信息修改彙總--------"); foreach (System.Reflection.PropertyInfo item in properties) {string name = item.Name; object oldValue = item.GetValue(oldModel); object newValue = item.GetValue(newModel); if (!oldValue.Equals(newValue)) { Console.WriteLine(name + " :由[" + oldValue + "] 改為 [" + newValue + "]"); } } }
從運行結果來看我們已經獲取到了修改的內容,美中不足的是“Name”和“Age”,如何以中文顯示屬性名,接下來將利用C#的特性來實現
新建一個自定義的特性類TableAttribute
/* 參數 validon 規定特性可被放置的語言元素。它是枚舉器 AttributeTargets 的值的組合。預設值是 AttributeTargets.All。 參數 allowmultiple(可選的)為該特性的 AllowMultiple 屬性(property)提供一個布爾值。如果為 true,則該特性是多用的。預設值是 false(單用的)。 參數 inherited(可選的)為該特性的 Inherited 屬性(property)提供一個布爾值。如果為 true,則該特性可被派生類繼承。預設值是 false(不被繼承)。 */ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public class TableAttribute : System.Attribute { private string fieldName; private string tableName; /// <summary> /// 表名 /// </summary> public string TableName { get { return tableName; } set { tableName = value; } } /// <summary> /// 欄位名 /// </summary> public string FieldName { get { return fieldName; } set { fieldName = value; } } }
接著修改User類,加上自定義的特性TableAttribute
/// <summary> /// 用戶信息實體類 /// </summary> [TableAttribute(TableName = "用戶信息")] public class User { private string name; [TableAttribute(FieldName = "姓名")] public string Name { get { return name; } set { name = value; } } private string age; [TableAttribute(FieldName = "年齡")] public string Age { get { return age; } set { age = value; } } private string sex; [TableAttribute(FieldName = "性別")] public string Sex { get { return sex; } set { sex = value; } } }
最後修改一下CompareModel這個方法
1 /// <summary> 2 /// Model對比 3 /// </summary> 4 /// <typeparam Name="T"></typeparam> 5 /// <param Name="oldModel"></param> 6 /// <param Name="newModel"></param> 7 private static void CompareModel<T>(T oldModel, T newModel) where T : class 8 { 9 string changeStr = string.Empty; 10 PropertyInfo[] properties = oldModel.GetType().GetProperties(); 11 Console.WriteLine("--------用戶信息修改彙總--------"); 12 foreach (System.Reflection.PropertyInfo item in properties) 13 { 14 TableAttribute tableAttribute = item.GetCustomAttribute<TableAttribute>(); 15 string name = item.Name; 16 if (tableAttribute != null) 17 name = tableAttribute.FieldName; 18 object oldValue = item.GetValue(oldModel); 19 object newValue = item.GetValue(newModel); 20 if (!oldValue.Equals(newValue)) 21 { 22 Console.WriteLine(name + " :由[" + oldValue + "] 改為 [" + newValue + "]"); 23 } 24 } 25 }
我們看一下運行結果
完整demo下載:https://files.cnblogs.com/files/LikeHeart/ExampleReflection.zip
(完)