当前项目需要记录变更记录,即用户在进行编辑后,将变更操作记录下来。但是数据没有发生变化,则不记录。

代码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#判断两个对象和对象中的属性是否相同(以及记录对象中的哪些字段,和详细的改变情况)的更多相关文章

  1. 将source类中的属性值赋给target类中对应的属性

    /** * 对象的属性值拷贝 * <p> * 将source对象中的属性值赋值到target对象中的属性,属性名一样,类型一样 * <p> * example: * <p ...

  2. LinearLayout的gravity属性以及其子元素的layout_gravity何时有效;RelativeLayout如何调整其子元素位置只能用子元素中的属性来控制,用RelativeLayout中的gravity无法控制!!!

    LinearLayout的gravity属性以及其子元素的layout_gravity何时有效:RelativeLayout如何调整其子元素位置只能用子元素中的属性来控制,用RelativeLayou ...

  3. 微信小程序:给data中对象中的属性设置值与给data中的属性或对象或数组设置值的区别

    一.给data中的属性或对象或数组设置值,属性名不需要加引号 this.setData({ material: param, // 这里material为对象 } this.setData({   d ...

  4. 修改表单元素中placeholder属性样式、清除IE浏览器中input元素的清除图标和眼睛图标

    一.修改input元素placeholder属性样式 在做项目的时候,一般表单元素的placeholder属性样式都是使用浏览器默认的,但有时候为了追求设计上的美感需要修表单元素的placeholde ...

  5. 用泛型方法Java从实体中提取属性值,以及在泛型方法中的使用

    public <T> T getFieldValue(Object target, String fieldName, Class<T> typeName) { try { O ...

  6. JavaScript 深入了解对象中的属性

    本篇主要介绍JS中对象的属性,包括:属性的分类.访问方式.检测属性.遍历属性以及属性特性等内容. 目录 1. 介绍:描述属性的命名方式.查找路径以及分类 2. 属性的访问方式:介绍'.'访问方式.'[ ...

  7. 在 WPF 中获取一个依赖对象的所有依赖项属性

    原文:在 WPF 中获取一个依赖对象的所有依赖项属性 本文介绍如何在 WPF 中获取一个依赖对象的所有依赖项属性. 本文内容 通过 WPF 标记获取 通过设计器专用方法获取 通过 WPF 标记获取 p ...

  8. 遍历js对象中的属性

    可以使用js自带的for in.也可以使用Ext JS中的方法来遍历js对象中的属性 代码如下: /** 遍历对象 */ var person = {name:'张泰松',age:28}; //js方 ...

  9. 深入理解JavaScript中的属性和特性

    深入理解JavaScript中的属性和特性 JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaSc ...

随机推荐

  1. 基于vue技术的企业移动办公系统的设计与实现

    如何打包: http://www.cnblogs.com/smilehuanxiao/p/7693858.html http://www.cnblogs.com/1314y/p/6207153.htm ...

  2. 深入理解redis数据类型

    转载请注明出处:https://www.cnblogs.com/wenjunwei/p/9720033.html redis的存储模型 redis不是普通的键值对存储,它实际上是一个数据结构存储服务器 ...

  3. pytorch模型部署在MacOS或者IOS

    pytorch训练出.pth模型如何在MacOS上或者IOS部署,这是个问题. 然而我们有了onnx,同样我们也有了coreML. ONNX: onnx是一种针对机器学习设计的开放式文件格式,用来存储 ...

  4. SHELL脚本--read命令

    bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 1.1 shell read简介 要与Linux交互,脚本获取 ...

  5. YARN集群的mapreduce测试(六)

    两张表链接操作(分布式缓存): ----------------------------------假设:其中一张A表,只有20条数据记录(比如group表)另外一张非常大,上亿的记录数量(比如use ...

  6. AvosCloud的文件存储 Demo

    时间戳:201310142227 废话少说,直接上代码: package com.dannalapp.main; import com.avos.avoscloud.GetCallback; impo ...

  7. SVN服务器本地搭建与使用

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6623026.html  使用SVN进行代码管理,需要搭建服务端资源库,然后在使用SVN的电脑安装SVN客户端或 ...

  8. MyISAM和InnoDB区别详解

    MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然性能极佳,但却有一个缺点 ...

  9. vuejs2.0与1.x版本中怎样使用js实时访问input的值的变化

    vuejs 2.0中js实时监听input 在2.0的版本中,vuejs把v-el 和 v-ref 合并为一个 ref 属性了,可以在组件实例中通过 $refs 来调用.这意味着 v-el:my-el ...

  10. touch.js 拖动、缩放、旋转 (鼠标手势)

    可以实现手势操作:拖动.缩放.旋转.封装好的脚本方法是这样的: var cat = window.cat || {}; cat.touchjs = { left: 0, top: 0, scaleVa ...