C#反射的简单应用
Posted 李公子lm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#反射的简单应用相关的知识,希望对你有一定的参考价值。
使用场景
假如我们需要做这样一个功能,用户可以修改一个列表里的信息,但是系统里需要记录用户修改了哪一条记录的哪几个字段,把改变的的字段之前的旧的数据保留下来,方便用户可以追溯数据,就好像QQ可以查看历史头像一样,User
表需要更新,但是同时需要在UserHistory
表里把旧的记录保存起来,我们可以怎么做呢?
这里我们把问题简单梳理下,每一条记录可以抽象为一个实体UserDto
,用户修改之后提交的也抽象为UserDto
,那就变成了比较同一个实体的不同属性的值了。
那就简单了,上代码。
public static void CompareTwoEntity<T>(T oldModel, T newModel)
{
//用来存放比较后的结果
var entity = new CompareJson();
Type typeDescription = typeof(DescriptionAttribute);
if (oldModel != null && newModel != null)
{
//反射获取类(泛型)的所有属性信息
System.Reflection.PropertyInfo[] mPi = typeof(T).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
var oldData = new List<OldData>();
var newData = new List<NewData>();
//循环获取每一个属性的信息
for (int i = 0; i < mPi.Length; i++)
{
System.Reflection.PropertyInfo pi = mPi[i];
object[] arr = pi.GetCustomAttributes(typeDescription, true);
//获取类的属性
string atrr = arr.Length > 0 ? ((DescriptionAttribute)arr[0]).Description : pi.Name;
//获取属性值
object oldObj = pi.GetValue(oldModel, null);
object newObj = pi.GetValue(newModel, null);
string oldValue = oldObj == null ? "" : oldObj.ToString();
string newValue = newObj == null ? "" : newObj.ToString();
//判断值是否相同,不相同则把旧值和新值都保存起来。
if (oldValue != newValue)
{
oldData.Add(new OldData { field = atrr,value=oldValue});
newData.Add(new NewData { field = atrr,value=newValue});
}
}
entity.oldData = oldData;
entity.newData = newData;
var json = Newtonsoft.Json.JsonConvert.SerializeObject(entity);
Console.WriteLine(json);
}
}
这里比较的必须是一个相同的实体不同的实例,通过反射获取类的所有的属性信息,然后循环获取每一个属性的值进行比较,不相同的则把属性和值都保存起来。
这里我们测试一下,实例化一个类两次。
var oldUser = new User
{
Id = "1",
Age = "21",
Gender = "女",
Name = "李四"
};
var newUser = new User
{
Id = "1",
Age = "21",
Gender = "女",
Name = "丽丽"
};
从上面的代码可以看出,就一个Name
属性不一样,接下来看运行结果。
已经成功的找出来了。
以下是完整代码。
using System.Runtime.Caching;
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Caching.Memory;
using System.Linq;
using System.ComponentModel;
using System.Net;
using System.Diagnostics;
namespace TestProject
{
class Program
{
static void Main(string[] args)
{
var oldUser = new User
{
Id = "1",
Age = "21",
Gender = "女",
Name = "李四"
};
var newUser = new User
{
Id = "1",
Age = "21",
Gender = "女",
Name = "丽丽"
};
CompareTwoEntity(oldUser, newUser);
Console.ReadKey();
}
public static void CompareTwoEntity<T>(T oldModel, T newModel)
{
//用来存放比较后的结果
var entity = new CompareJson();
Type typeDescription = typeof(DescriptionAttribute);
if (oldModel != null && newModel != null)
{
//反射获取类(泛型)的所有属性信息
System.Reflection.PropertyInfo[] mPi = typeof(T).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
var oldData = new List<OldData>();
var newData = new List<NewData>();
//循环获取每一个属性的信息
for (int i = 0; i < mPi.Length; i++)
{
System.Reflection.PropertyInfo pi = mPi[i];
object[] arr = pi.GetCustomAttributes(typeDescription, true);
//获取类的属性
string atrr = arr.Length > 0 ? ((DescriptionAttribute)arr[0]).Description : pi.Name;
//获取属性值
object oldObj = pi.GetValue(oldModel, null);
object newObj = pi.GetValue(newModel, null);
string oldValue = oldObj == null ? "" : oldObj.ToString();
string newValue = newObj == null ? "" : newObj.ToString();
//判断值是否相同,不相同则把旧值和新值都保存起来。
if (oldValue != newValue)
{
oldData.Add(new OldData { field = atrr,value=oldValue});
newData.Add(new NewData { field = atrr,value=newValue});
}
}
entity.oldData = oldData;
entity.newData = newData;
var json = Newtonsoft.Json.JsonConvert.SerializeObject(entity);
Console.WriteLine(json);
}
}
}
class User
{
public string Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string Age { get; set; }
}
class CompareJson
{
public List<OldData> oldData { get; set; }
public List<NewData> newData { get; set; }
}
class OldData
{
public string field { get; set; }
public string value { get; set; }
}
class NewData
{
public string field { get; set; }
public string value { get; set; }
}
}
study hard and make progress every day.
以上是关于C#反射的简单应用的主要内容,如果未能解决你的问题,请参考以下文章