c#判断两个对象和对象中的属性是否相同(以及记录对象中的哪些字段,和详细的改变情况)
当前项目需要记录变更记录,即用户在进行编辑后,将变更操作记录下来。但是数据没有发生变化,则不记录。
代码1:(仅仅返回是否变化的标识)
/// <summary>
/// 反射对比实体属性变更
/// </summary>
/// <typeparam name="T"></typeparam>
public class CompareEntry<T>
{
/// <summary>
/// 编辑之前的对象和编辑后的对象进行对比
/// </summary>
/// <returns></returns>
public bool CompareDTO(T BeforeDTO, T AfterDTO)
{
bool IsEqual = true; if (BeforeDTO == null || AfterDTO == null)
{
IsEqual = false;
}
else if (BeforeDTO.Equals(DBNull.Value) || AfterDTO.Equals(DBNull.Value))
{
IsEqual = false;
}else if (BeforeDTO.GetType() != AfterDTO.GetType())
{
IsEqual = false;
return IsEqual;
}
else if (BeforeDTO is int || BeforeDTO is short || BeforeDTO is long || BeforeDTO is float || BeforeDTO is double || BeforeDTO is decimal)
{
//int 01与1
if (BeforeDTO is int)
{
if (Convert.ToInt32(BeforeDTO) != Convert.ToInt32(AfterDTO))
{
IsEqual = false;
}
}
else if (BeforeDTO is short)
{
if (Convert.ToInt16(BeforeDTO) != Convert.ToInt16(AfterDTO))
{
IsEqual = false;
}
}
else if (BeforeDTO is long)
{
if (Convert.ToInt64(BeforeDTO) != Convert.ToInt64(AfterDTO))
{
IsEqual = false;
}
}
else if (BeforeDTO is float)
{
if (Convert.ToSingle(BeforeDTO) != Convert.ToSingle(AfterDTO))
{
IsEqual = false;
}
}
else if (BeforeDTO is double)
{
if (Convert.ToDouble(BeforeDTO) != Convert.ToDouble(AfterDTO))
{
IsEqual = false;
}
}
else if (BeforeDTO is decimal)
{
if (Convert.ToDecimal(BeforeDTO) == Convert.ToDecimal(AfterDTO))
{
IsEqual = false;
}
}
}
else
{
var beforeMembers = BeforeDTO.GetType().GetProperties();
var afterMembers = AfterDTO.GetType().GetProperties();
for (int i = ; i < beforeMembers.Length; i++)
{
var beforeVal = beforeMembers[i].GetValue(BeforeDTO, null);
var afterVal = afterMembers[i].GetValue(AfterDTO, null);
var beforeValue = beforeVal == null ? null : beforeVal.ToString();
var afterValue = afterVal == null ? null : afterVal.ToString();
if (beforeValue != afterValue)
{
IsEqual = false;
break;
}
}
} return IsEqual;
}
}
调整后的代码:(返回标识以及详细变更记录)
/// <summary>
///
/// </summary>
public class CompareResult
{
/// <summary>
///
/// </summary>
public bool IsChange { get; set; }
/// <summary>
/// 变跟内容
/// </summary>
public string ChangeContent { get; set; }
} /// <summary>
/// 对比实体属性变更(利用反射)
/// </summary>
public class CompareEntry
{
/// <summary>
///
/// </summary>
/// <returns></returns>
public CompareResult CompareDTO(object BeforeDTO, object AfterDTO)
{
CompareResult result = new CompareResult();
bool b = false; if (BeforeDTO == null && AfterDTO != null)
{
b = true;
}
else if (BeforeDTO != null && AfterDTO == null)
{
b = true;
}
else if (BeforeDTO.Equals(DBNull.Value) && !AfterDTO.Equals(DBNull.Value))
{
b = true;
}
else if (!BeforeDTO.Equals(DBNull.Value) && AfterDTO.Equals(DBNull.Value))
{
b = true;
}
else if (BeforeDTO.GetType() != AfterDTO.GetType())
{
result.IsChange = true;
return result;
}
else if (BeforeDTO is int || BeforeDTO is short || BeforeDTO is long || BeforeDTO is float || BeforeDTO is double || BeforeDTO is decimal)
{
if (BeforeDTO is int)
{
if (Convert.ToInt32(BeforeDTO) != Convert.ToInt32(AfterDTO))
{
b = true;
}
}
else if (BeforeDTO is short)
{
if (Convert.ToInt16(BeforeDTO) != Convert.ToInt16(AfterDTO))
{
b = true;
}
}
else if (BeforeDTO is long)
{
if (Convert.ToInt64(BeforeDTO) != Convert.ToInt64(AfterDTO))
{
b = true;
}
}
else if (BeforeDTO is float)
{
if (Convert.ToSingle(BeforeDTO) != Convert.ToSingle(AfterDTO))
{
b = true;
}
}
else if (BeforeDTO is double)
{
if (Convert.ToDouble(BeforeDTO) != Convert.ToDouble(AfterDTO))
{
b = true;
}
}
else if (BeforeDTO is decimal)
{
if (Convert.ToDecimal(BeforeDTO) == Convert.ToDecimal(AfterDTO))
{
b = true;
}
}
}
else
{
StringBuilder content = new StringBuilder();
var beforeMembers = BeforeDTO.GetType().GetProperties();
var afterMembers = AfterDTO.GetType().GetProperties();
for (int i = ; i < beforeMembers.Length; i++)
{
var beforeVal = beforeMembers[i].GetValue(BeforeDTO, null);
var afterVal = afterMembers[i].GetValue(AfterDTO, null);
var beforeValue = beforeVal == null ? null : beforeVal.ToString();
var afterValue = afterVal == null ? null : afterVal.ToString();
if (beforeValue != afterValue)
{
b = true;
content.Append(beforeMembers[i].Name+"("+ beforeValue+"->"+afterValue+")");
}
}
result.IsChange = b;
result.ChangeContent = content.ToString();
} return result;
}
}
注意,引用类型进行对比的时候,需要在编辑之前对对象进行拷贝,让拷贝的对象与编辑后的对象进行对比。(因为引用类型不同于值类型,值类型每次操作都会产生一个新的对象,而引用类型在new一个新对象赋值时,其实是在堆上创建了一个内存地址,指向的仍然是原对象,对它操作原对象也会发生变化。所以只有通过拷贝复制一个新对象)
c#判断两个对象和对象中的属性是否相同(以及记录对象中的哪些字段,和详细的改变情况)的更多相关文章
- 将source类中的属性值赋给target类中对应的属性
/** * 对象的属性值拷贝 * <p> * 将source对象中的属性值赋值到target对象中的属性,属性名一样,类型一样 * <p> * example: * <p ...
- LinearLayout的gravity属性以及其子元素的layout_gravity何时有效;RelativeLayout如何调整其子元素位置只能用子元素中的属性来控制,用RelativeLayout中的gravity无法控制!!!
LinearLayout的gravity属性以及其子元素的layout_gravity何时有效:RelativeLayout如何调整其子元素位置只能用子元素中的属性来控制,用RelativeLayou ...
- 微信小程序:给data中对象中的属性设置值与给data中的属性或对象或数组设置值的区别
一.给data中的属性或对象或数组设置值,属性名不需要加引号 this.setData({ material: param, // 这里material为对象 } this.setData({ d ...
- 修改表单元素中placeholder属性样式、清除IE浏览器中input元素的清除图标和眼睛图标
一.修改input元素placeholder属性样式 在做项目的时候,一般表单元素的placeholder属性样式都是使用浏览器默认的,但有时候为了追求设计上的美感需要修表单元素的placeholde ...
- 用泛型方法Java从实体中提取属性值,以及在泛型方法中的使用
public <T> T getFieldValue(Object target, String fieldName, Class<T> typeName) { try { O ...
- JavaScript 深入了解对象中的属性
本篇主要介绍JS中对象的属性,包括:属性的分类.访问方式.检测属性.遍历属性以及属性特性等内容. 目录 1. 介绍:描述属性的命名方式.查找路径以及分类 2. 属性的访问方式:介绍'.'访问方式.'[ ...
- 在 WPF 中获取一个依赖对象的所有依赖项属性
原文:在 WPF 中获取一个依赖对象的所有依赖项属性 本文介绍如何在 WPF 中获取一个依赖对象的所有依赖项属性. 本文内容 通过 WPF 标记获取 通过设计器专用方法获取 通过 WPF 标记获取 p ...
- 遍历js对象中的属性
可以使用js自带的for in.也可以使用Ext JS中的方法来遍历js对象中的属性 代码如下: /** 遍历对象 */ var person = {name:'张泰松',age:28}; //js方 ...
- 深入理解JavaScript中的属性和特性
深入理解JavaScript中的属性和特性 JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaSc ...
随机推荐
- Spring系列之手写注解与配置文件的解析
目录 Spring系列之IOC的原理及手动实现 Spring系列之DI的原理及手动实现 Spring系列之AOP的原理及手动实现 引入 在前面我们已经完成了IOC,DI,AOP的实现,基本的功能都已经 ...
- ES6躬行记(9)——字符串
在介绍字符串之前,有必要先了解一点Unicode的基础知识,有助于理解ES6提供的新功能和新特性. 一.Unicode Unicode是一种字符集(即多个字符的集合),它的目标是涵盖世界上的所有字符, ...
- Zookeeper Client简介
直接使用zk的api实现业务功能比较繁琐.因为要处理session loss,session expire等异常,在发生这些异常后进行重连.又因为ZK的watcher是一次性的,如果要基于wather ...
- 南大算法设计与分析课程OJ答案代码(4)--变位词、三数之和
问题 A: 变位词 时间限制: 2 Sec 内存限制: 10 MB提交: 322 解决: 59提交 状态 算法问答 题目描述 请大家在做oj题之前,仔细阅读关于抄袭的说明http://www.bi ...
- C# Redis安装 使用教程
前言:lz自打工作以来第一次遇到电脑问题需要重装系统,全盘格式化.打击是沉痛的.特别伤. 然后需要重新在本地部署 redis.这是写这篇博客的原因.希望对大家有所帮助,安装资源和引用DLL可以引用 ...
- WinForm DataGridView 绑定泛型List(List<T>)/ArrayList不显示的原因和解决
背景:无意间遇到了一个不大不小的问题,希望对一些遇到的人有所帮助! 一.问题 WinForm DataGridView 绑定泛型List (List<T>)/ArrayList不显示,UI ...
- SQL Server 怎么在分页获取数据的同时获取到总记录数
SQL Server 获取数据的总记录数,有两种方式: 1.先分页获取数据,然后再查询一遍数据库获取到总数量 2.使用count(1) over()获取总记录数量 SELECT * FROM ( SE ...
- 第四讲 smart qq 获取联系人信息 ,分组 好友 群聊
首先从post一下 http://s.web2.qq.com/api/get_user_friends2 这个链接获取分组categories ,好友信息 friends,info. string ...
- WPF,强制捕获鼠标事件,鼠标移出控件外依然可以执行强制捕获的鼠标事件
在WPF中,只有鼠标位置在某个控件上的时候才会触发该控件的鼠标事件.例如,有两个控件都注册了MouseDown和MouseUp事件,在控件1上按下鼠标,不要放开,移动到控件2上再放开.在这个过程中,控 ...
- 升级mac自带的python
系统自带的Python $ which python 终端输出 /usr/bin/python 使用Homebrew安装最新的Python2 为什么要使用Homebrew安装Python? 总能下载到 ...