查看: 501|回复: 0

[ASP.NET教程] 反射实现Model修改前后的内容对比

发表于 2018-4-25 08:00:02

在开发过程中,我们会遇到这样一个问题,编辑了一个对象之后,我们想要把这个对象修改了哪些内容保存下来,以便将来查看和追责。

首先我们要创建一个User类

  1. 1 public class User
  2. 2 {
  3. 3 private string name;
  4. 4 public string Name
  5. 5 {
  6. 6 get { return name; }
  7. 7 set { name = value; }
  8. 8 }
  9. 9 private string age;
  10. 10 public string Age
  11. 11 {
  12. 12 get { return age; }
  13. 13 set { age = value; }
  14. 14 }
  15. 15 private string sex;
  16. 16 public string Sex
  17. 17 {
  18. 18 get { return sex; }
  19. 19 set { sex = value; }
  20. 20 }
  21. 21 }
复制代码

然后在Main函数中声明并初始化一个User对象

  1. 1 User userA = new User()
  2. 2 {
  3. 3 Name = "李四",
  4. 4 Age = "25",
  5. 5 Sex = "男",
  6. 6 };
复制代码

因为要对比对象编辑前后的内容,所以需要备份一下这个UserA,我们来个深拷贝

  1. 1 User userB = DeepCopyByXml<User>(userA);
复制代码
  1. 1 /// <summary>
  2. 2 /// 深拷贝
  3. 3 /// </summary>
  4. 4 /// <typeparam name="T"></typeparam>
  5. 5 /// <param name="obj"></param>
  6. 6 /// <returns></returns>
  7. 7 public static T DeepCopyByXml<T>(T obj) where T : class
  8. 8 {
  9. 9 object retval;
  10. 10 using (MemoryStream ms = new MemoryStream())
  11. 11 {
  12. 12 XmlSerializer xml = new XmlSerializer(typeof(T));
  13. 13 xml.Serialize(ms, obj);
  14. 14 ms.Seek(0, SeekOrigin.Begin);
  15. 15 retval = xml.Deserialize(ms);
  16. 16 ms.Close();
  17. 17 }
  18. 18 return (T)retval;
  19. 19 }
复制代码

接下来的工作是修改UserA的属性,然后和UserB对比,利用反射来实现该功能

  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. {string name = item.Name;
  14. object oldValue = item.GetValue(oldModel);
  15. object newValue = item.GetValue(newModel);
  16. if (!oldValue.Equals(newValue))
  17. {
  18. Console.WriteLine(name + " :由[" + oldValue + "] 改为 [" + newValue + "]");
  19. }
  20. }
  21. }
复制代码

从运行结果来看我们已经获取到了修改的内容,美中不足的是“Name”和“Age”,如何以中文显示属性名,接下来将利用C#的特性来实现

新建一个自定义的特性类TableAttribute

  1. /*
  2. 参数 validon 规定特性可被放置的语言元素。它是枚举器 AttributeTargets 的值的组合。默认值是 AttributeTargets.All。
  3. 参数 allowmultiple(可选的)为该特性的 AllowMultiple 属性(property)提供一个布尔值。如果为 true,则该特性是多用的。默认值是 false(单用的)。
  4. 参数 inherited(可选的)为该特性的 Inherited 属性(property)提供一个布尔值。如果为 true,则该特性可被派生类继承。默认值是 false(不被继承)。
  5. */
  6. [AttributeUsage(AttributeTargets.Class |
  7. AttributeTargets.Field |
  8. AttributeTargets.Property,
  9. AllowMultiple = false,
  10. Inherited = false)]
  11. public class TableAttribute : System.Attribute
  12. {
  13. private string fieldName;
  14. private string tableName;
  15. /// <summary>
  16. /// 表名
  17. /// </summary>
  18. public string TableName
  19. {
  20. get { return tableName; }
  21. set { tableName = value; }
  22. }
  23. /// <summary>
  24. /// 字段名
  25. /// </summary>
  26. public string FieldName
  27. {
  28. get { return fieldName; }
  29. set { fieldName = value; }
  30. }
  31. }
复制代码

接着修改User类,加上自定义的特性TableAttribute

  1. /// <summary>
  2. /// 用户信息实体类
  3. /// </summary>
  4. [TableAttribute(TableName = "用户信息")]
  5. public class User
  6. {
  7. private string name;
  8. [TableAttribute(FieldName = "姓名")]
  9. public string Name
  10. {
  11. get { return name; }
  12. set { name = value; }
  13. }
  14. private string age;
  15. [TableAttribute(FieldName = "年龄")]
  16. public string Age
  17. {
  18. get { return age; }
  19. set { age = value; }
  20. }
  21. private string sex;
  22. [TableAttribute(FieldName = "性别")]
  23. public string Sex
  24. {
  25. get { return sex; }
  26. set { sex = value; }
  27. }
  28. }
复制代码

最后修改一下CompareModel这个方法

  1. 1 /// <summary>
  2. 2 /// Model对比
  3. 3 /// </summary>
  4. 4 /// <typeparam Name="T"></typeparam>
  5. 5 /// <param Name="oldModel"></param>
  6. 6 /// <param Name="newModel"></param>
  7. 7 private static void CompareModel<T>(T oldModel, T newModel) where T : class
  8. 8 {
  9. 9 string changeStr = string.Empty;
  10. 10 PropertyInfo[] properties = oldModel.GetType().GetProperties();
  11. 11 Console.WriteLine("--------用户信息修改汇总--------");
  12. 12 foreach (System.Reflection.PropertyInfo item in properties)
  13. 13 {
  14. 14 <strong> TableAttribute tableAttribute = item.GetCustomAttribute<TableAttribute>();
  15. </strong>15 string name = item.Name;
  16. 16 <strong>if (tableAttribute != null)
  17. </strong>17 <strong>name = tableAttribute.FieldName;
  18. </strong>18 object oldValue = item.GetValue(oldModel);
  19. 19 object newValue = item.GetValue(newModel);
  20. 20 if (!oldValue.Equals(newValue))
  21. 21 {
  22. 22 Console.WriteLine(name + " :由[" + oldValue + "] 改为 [" + newValue + "]");
  23. 23 }
  24. 24 }
  25. 25 }
复制代码

我们看一下运行结果

完整demo下载:https://files.cnblogs.com/files/LikeHeart/ExampleReflection.zip

(完)



回复

使用道具 举报