在开发过程中,我们会遇到这样一个问题,编辑了一个对象之后,我们想要把这个对象修改了哪些内容保存下来,以便将来查看和追责。
首先我们要创建一个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
(完)