反射实现Model修改前后的内容对比
在开发过程中,我们会遇到这样一个问题,编辑了一个对象之后,我们想要把这个对象修改了哪些内容保存下来,以便将来查看和追责。
首先我们要创建一个User类
- public class User
- {
- private string name;
- public string Name
- {
- get { return name; }
- set { name = value; }
- }
- private string age;
- public string Age
- {
- get { return age; }
- set { age = value; }
- }
- private string sex;
- public string Sex
- {
- get { return sex; }
- set { sex = value; }
- }
- }
然后在Main函数中声明并初始化一个User对象
- User userA = new User()
- {
- Name = "李四",
- Age = "",
- Sex = "男",
- };
因为要对比对象编辑前后的内容,所以需要备份一下这个UserA,我们来个深拷贝
- User userB = DeepCopyByXml<User>(userA);
- /// <summary>
- /// 深拷贝
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="obj"></param>
- /// <returns></returns>
- public static T DeepCopyByXml<T>(T obj) where T : class
- {
- object retval;
- using (MemoryStream ms = new MemoryStream())
- {
- XmlSerializer xml = new XmlSerializer(typeof(T));
- xml.Serialize(ms, obj);
- ms.Seek(, SeekOrigin.Begin);
- retval = xml.Deserialize(ms);
- ms.Close();
- }
- return (T)retval;
- }
接下来的工作是修改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这个方法
- /// <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)
- {
- TableAttribute tableAttribute = item.GetCustomAttribute<TableAttribute>();
- string name = item.Name;
- if (tableAttribute != null)
- name = tableAttribute.FieldName;
- object oldValue = item.GetValue(oldModel);
- object newValue = item.GetValue(newModel);
- if (!oldValue.Equals(newValue))
- {
- Console.WriteLine(name + " :由[" + oldValue + "] 改为 [" + newValue + "]");
- }
- }
- }
我们看一下运行结果
完整demo下载:https://files.cnblogs.com/files/LikeHeart/ExampleReflection.zip
(完)
反射实现Model修改前后的内容对比的更多相关文章
- 反射实现Model修改前后的内容对比 【API调用】腾讯云短信 Windows操作系统下Redis服务安装图文详解 Redis入门学习
反射实现Model修改前后的内容对比 在开发过程中,我们会遇到这样一个问题,编辑了一个对象之后,我们想要把这个对象修改了哪些内容保存下来,以便将来查看和追责. 首先我们要创建一个User类 1 p ...
- Charles系列三:Charles打断点(包含修改请求,修改返回的内容),模拟慢速网络(弱网测试),域名映射,过滤请求,接口调试,打压测试
一:Charles断点的使用(包含修改请求,修改返回的数据) 设置断点来修改请求和返回的数据,在开发过程中可以模拟多种响应.步骤如下: 1.添加断点方法有两种: 方法1:找到Charles中菜单项Pr ...
- 修改placeholder提示内容的颜色以及文本框输入文字内容的颜色
一般表单文本框提示信息:placeholder=" ",默认颜色是灰色的,输入文本信息也是默认为黑色的,如图所示: 修改placeholder提示内容的颜色关键代码及实现: 实现输 ...
- ios UIWebView截获html并修改便签内容(转载)
ios UIWebView截获html并修改便签内容 博客分类: iphone开发iphone开发phoneGap uiwebviewstringByEvaluatingJavaScriptFromS ...
- IOS UIWebView截获html并修改便签内容,宽度自适应
需求:混合应用UIWebView打开html后,UIWebView有左右滚动条,要去掉左右滚动效果: 方法:通过js截获UIWebView中的html,然后修改html标签内容: 实例代码: 服 ...
- ios UIWebView截获html并修改便签内容
需求:混合应用UIWebView打开html后,UIWebView有左右滚动条,要去掉左右滚动效果: 方法:通过js截获UIWebView中的html,然后修改html标签内容: 实例代码: 服务器端 ...
- Mac下显示隐藏文件 以及修改 hosts文件内容
修改hosts 文件内容: 进入etc 文件夹,找到hosts 文件,把该文件复制出来,修改完里面的内容后,先把etc中的hosts 文件删除,然后在把修改后的文件脱机去 可能需要管理员的密码,你输入 ...
- 简单的爬虫爬的完整的<img>标签,修改正则即可修改爬取内容
简单的爬虫爬的完整的<img>标签,生成<img>标签结果文件与爬虫经历的网页. <?php/** 从给定的url获取html内容** */function _getUr ...
- OpenXml修改word特定内容
采用OpenXml来修改word特定内容,如下: word: OpenXml修改word之前: OpenXml修改word之后: 代码: string path = @"C:\Users\A ...
随机推荐
- fastscript例子一
fastscript例子一 fastscript例子一 unit Unit1; interface usesWinapi.Windows, Winapi.Messages, System.SysU ...
- netcore的NLog使用小记
1. 启动应用程序日志配置 修改Program.cs,在WebHostBuilder构建时配置日志 public static IWebHostBuilder CreateWebHostBuilder ...
- 初识Identity并添加身份验证管理页面
目录 初识Identity并添加身份验证管理页面 前言 什么是ASP.NET Core Identity 创建带有身份验证的WebApp 尝试运行 检查解决方案中的项目文件 发现问题 原因 解决问题 ...
- WPF TreeView IsExpanded 绑定不上的问题
最近项目上需要通过MVVM来控制TreeView,其中需要需要控制通过搜索来定位某个节点,正常逻辑下,首先通过需要在树上面找到该节点,然后选中该节点,并将该节点的父节点展开,这个时候需要通过MVVM来 ...
- 迁移桌面程序到MS Store(4)——桌面程序调用Win10 API
上一篇我们讨论了如何在转制的桌面程序中,通过StartupTask来实现转制版本的开机自启动.实际操作中,我们通过编辑Packaging工程中的Package.appxmanifest文件,来添加自启 ...
- EMACS快捷键
C = Control M = Meta = Alt | Esc Del = Backspace 基本快捷键(Basic) C-x C-f "find"文件, 即在缓冲区打开/新建 ...
- 【算法python实现】 -- 不同路径
原题:https://leetcode-cn.com/problems/unique-paths/ 问题描述 n行m列的表格,从a[0][0]出发,每次只能右移一步或者下移一步,求到a[n-1][m- ...
- word2vec的原理(一)
最近上了公司的新员工基础培训课,又对NLP重新产生的兴趣.NLP的第一步大家知道的就是不停的写正则,那个以前学的还可以就不看了.接着就是我们在把NLP的词料在传入神经网络之前的一个预处理,最经典的就是 ...
- linux上安装redis4.0.9
redis安装从3.0的版本到现在4.0的版本,现在装一个4.0的版本供大家学习使用. 先yum安装gcc yum -y install gcc 已加载插件:fastestmirror, langpa ...
- CSS之浏览器默认样式问题
今天自己写css样式时,其中用到了<ul>标签,设置了一系列效果后运行,发现位置与设置有出入.chrome上打开检查项,发现<ul>标签的styles底部多了以下一段: ul, ...