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

首先我们要创建一个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 = "",
  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(, SeekOrigin.Begin);
  15. retval = xml.Deserialize(ms);
  16. ms.Close();
  17. }
  18. return (T)retval;
  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. /// <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

(完)

反射实现Model修改前后的内容对比的更多相关文章

  1. 反射实现Model修改前后的内容对比 【API调用】腾讯云短信 Windows操作系统下Redis服务安装图文详解 Redis入门学习

    反射实现Model修改前后的内容对比   在开发过程中,我们会遇到这样一个问题,编辑了一个对象之后,我们想要把这个对象修改了哪些内容保存下来,以便将来查看和追责. 首先我们要创建一个User类 1 p ...

  2. Charles系列三:Charles打断点(包含修改请求,修改返回的内容),模拟慢速网络(弱网测试),域名映射,过滤请求,接口调试,打压测试

    一:Charles断点的使用(包含修改请求,修改返回的数据) 设置断点来修改请求和返回的数据,在开发过程中可以模拟多种响应.步骤如下: 1.添加断点方法有两种: 方法1:找到Charles中菜单项Pr ...

  3. 修改placeholder提示内容的颜色以及文本框输入文字内容的颜色

    一般表单文本框提示信息:placeholder=" ",默认颜色是灰色的,输入文本信息也是默认为黑色的,如图所示: 修改placeholder提示内容的颜色关键代码及实现: 实现输 ...

  4. ios UIWebView截获html并修改便签内容(转载)

    ios UIWebView截获html并修改便签内容 博客分类: iphone开发iphone开发phoneGap uiwebviewstringByEvaluatingJavaScriptFromS ...

  5. IOS UIWebView截获html并修改便签内容,宽度自适应

    需求:混合应用UIWebView打开html后,UIWebView有左右滚动条,要去掉左右滚动效果:  方法:通过js截获UIWebView中的html,然后修改html标签内容:  实例代码:  服 ...

  6. ios UIWebView截获html并修改便签内容

    需求:混合应用UIWebView打开html后,UIWebView有左右滚动条,要去掉左右滚动效果: 方法:通过js截获UIWebView中的html,然后修改html标签内容: 实例代码: 服务器端 ...

  7. Mac下显示隐藏文件 以及修改 hosts文件内容

    修改hosts 文件内容: 进入etc 文件夹,找到hosts 文件,把该文件复制出来,修改完里面的内容后,先把etc中的hosts 文件删除,然后在把修改后的文件脱机去 可能需要管理员的密码,你输入 ...

  8. 简单的爬虫爬的完整的<img>标签,修改正则即可修改爬取内容

    简单的爬虫爬的完整的<img>标签,生成<img>标签结果文件与爬虫经历的网页. <?php/** 从给定的url获取html内容** */function _getUr ...

  9. OpenXml修改word特定内容

    采用OpenXml来修改word特定内容,如下: word: OpenXml修改word之前: OpenXml修改word之后: 代码: string path = @"C:\Users\A ...

随机推荐

  1. fastscript例子一

    fastscript例子一   fastscript例子一 unit Unit1; interface usesWinapi.Windows, Winapi.Messages, System.SysU ...

  2. netcore的NLog使用小记

    1. 启动应用程序日志配置 修改Program.cs,在WebHostBuilder构建时配置日志 public static IWebHostBuilder CreateWebHostBuilder ...

  3. 初识Identity并添加身份验证管理页面

    目录 初识Identity并添加身份验证管理页面 前言 什么是ASP.NET Core Identity 创建带有身份验证的WebApp 尝试运行 检查解决方案中的项目文件 发现问题 原因 解决问题 ...

  4. WPF TreeView IsExpanded 绑定不上的问题

    最近项目上需要通过MVVM来控制TreeView,其中需要需要控制通过搜索来定位某个节点,正常逻辑下,首先通过需要在树上面找到该节点,然后选中该节点,并将该节点的父节点展开,这个时候需要通过MVVM来 ...

  5. 迁移桌面程序到MS Store(4)——桌面程序调用Win10 API

    上一篇我们讨论了如何在转制的桌面程序中,通过StartupTask来实现转制版本的开机自启动.实际操作中,我们通过编辑Packaging工程中的Package.appxmanifest文件,来添加自启 ...

  6. EMACS快捷键

    C = Control M = Meta = Alt | Esc Del = Backspace 基本快捷键(Basic) C-x C-f "find"文件, 即在缓冲区打开/新建 ...

  7. 【算法python实现】 -- 不同路径

    原题:https://leetcode-cn.com/problems/unique-paths/ 问题描述 n行m列的表格,从a[0][0]出发,每次只能右移一步或者下移一步,求到a[n-1][m- ...

  8. word2vec的原理(一)

    最近上了公司的新员工基础培训课,又对NLP重新产生的兴趣.NLP的第一步大家知道的就是不停的写正则,那个以前学的还可以就不看了.接着就是我们在把NLP的词料在传入神经网络之前的一个预处理,最经典的就是 ...

  9. linux上安装redis4.0.9

    redis安装从3.0的版本到现在4.0的版本,现在装一个4.0的版本供大家学习使用. 先yum安装gcc yum -y install gcc 已加载插件:fastestmirror, langpa ...

  10. CSS之浏览器默认样式问题

    今天自己写css样式时,其中用到了<ul>标签,设置了一系列效果后运行,发现位置与设置有出入.chrome上打开检查项,发现<ul>标签的styles底部多了以下一段: ul, ...