ly188:二话不说上代码
public static class MappingExtension { #region 对象值映射赋值(属性名称根据被指映射) /// <summary> /// 对象值映射赋值(属性名称根据被指映射) /// </summary> /// <typeparam name="T">需要赋值的对象:不能为空</typeparam> /// <typeparam name="TA">数据源:不能为空</typeparam> /// <param name="sourceInfo">数据源</param> /// <param name="resInfo">需要赋值的对象</param> public static void MappingTo<T, TA>(this TA sourceInfo, T resInfo) where T : class, new() where TA : class, new() { if (sourceInfo == null || resInfo == null) { return; } Type sourceType = typeof(TA); Type resType = typeof(T); //// 获取数据源public属性集合 PropertyInfo[] sourcePropertyInfoList = sourceType.GetProperties(); if (sourcePropertyInfoList != null) { //// 获取返回的对象的共有属性的名称集合,数据源不存在的不需要做赋值 var resProList = resType.GetProperties(); Dictionary<string, PropertyInfo> resNameProDic = new Dictionary<string, PropertyInfo>(); if (resProList != null) { foreach (var item in resProList) { var isIgnore = item.IsDefined(typeof(IgnoreAttribute), false); if (!isIgnore) { string resProName = item.Name; var mappingName = item.GetCustomAttribute<MappingNameAttribute>()?.MappingName; if (string.IsNullOrWhiteSpace(mappingName)) { resNameProDic.Add(resProName, item); } else { resNameProDic.Add(mappingName, item); } } } } //// 给对应(相同)的属性赋值 foreach (PropertyInfo sourcePropertyInfo in sourcePropertyInfoList) { string sourcePropertyInfoName = sourcePropertyInfo.Name; if (resNameProDic.ContainsKey(sourcePropertyInfoName)) { //// 获取数据源对应属性值 object sourceProValue = sourcePropertyInfo.GetValue(sourceInfo, null); //// 给返回的对象相同属性赋值 FillProValue(resInfo, sourcePropertyInfo, resNameProDic[sourcePropertyInfoName], sourceProValue); } } } } #endregion #region 对象值映射赋值(属性名称根据被指映射) /// <summary> /// 对象值映射赋值(属性名称根据被指映射) /// </summary> /// <typeparam name="T">需要赋值的对象:不能为空</typeparam> /// <typeparam name="TA">数据源:不能为空</typeparam> /// <param name="sourceList">数据源</param> /// <param name="resInfo">需要赋值的对象</param> public static void MappingToList<T, TA>(this List<TA> sourceList, List<T> resList) where T : class, new() where TA : class, new() { if (sourceList == null || resList == null) { return; } Type sourceType = typeof(TA); Type resType = typeof(T); //// 获取数据源public属性集合 PropertyInfo[] sourcePropertyInfoList = sourceType.GetProperties(); if (sourcePropertyInfoList != null) { //// 获取返回的对象的共有属性的名称集合,数据源不存在的不需要做赋值 var resProList = resType.GetProperties(); Dictionary<string, PropertyInfo> resNamePro = new Dictionary<string, PropertyInfo>(); if (resProList != null) { foreach (var item in resProList) { var isIgnore = item.IsDefined(typeof(IgnoreAttribute), false); if (!isIgnore) { string resProName = item.Name; var mappingName = item.GetCustomAttribute<MappingNameAttribute>()?.MappingName; if (string.IsNullOrWhiteSpace(mappingName)) { resNamePro.Add(resProName, item); } else { resNamePro.Add(mappingName, item); } } } } foreach (var sourceInfo in sourceList) { //// 给对应(相同)的属性赋值 T resInfo = new T(); //// 给对应(相同)的属性赋值 foreach (PropertyInfo sourcePropertyInfo in sourcePropertyInfoList) { string sourcePropertyInfoName = sourcePropertyInfo.Name; if (resNamePro.ContainsKey(sourcePropertyInfoName)) { //// 获取数据源对应属性值 object sourceProValue = sourcePropertyInfo.GetValue(sourceInfo, null); //// 给返回的对象相同属性赋值 FillProValue(resInfo, sourcePropertyInfo, resNamePro[sourcePropertyInfoName], sourceProValue); } } resList.Add(resInfo); } } } #endregion #region 对象值映射赋值(属性名称根据被指映射) /// <summary> /// 对象值映射赋值(属性名称根据被指映射) /// </summary> /// <typeparam name="T">需要赋值的对象:不能为空</typeparam> /// <typeparam name="TA">数据源:不能为空</typeparam> /// <param name="sourceList">数据源</param> /// <param name="resInfo">需要赋值的对象</param> public static void MappingToListFunc<T, TA>(this List<TA> sourceList, List<T> resList) where T : class, new() where TA : class, new() { if (sourceList == null || resList == null) { return; } Type sourceType = typeof(TA); Type resType = typeof(T); //// 获取数据源public属性集合 PropertyInfo[] sourcePropertyInfoList = sourceType.GetProperties(); if (sourcePropertyInfoList != null) { //// 获取返回的对象的共有属性的名称集合,数据源不存在的不需要做赋值 var resProList = resType.GetProperties(); Dictionary<string, PropertyInfo> resNamePro = new Dictionary<string, PropertyInfo>(); if (resProList != null) { foreach (var item in resProList) { var isIgnore = item.IsDefined(typeof(IgnoreAttribute), false); if (!isIgnore) { string resProName = item.Name; var mappingName = item.GetCustomAttribute<MappingNameAttribute>()?.MappingName; if (string.IsNullOrWhiteSpace(mappingName)) { resNamePro.Add(resProName, item); } else { resNamePro.Add(mappingName, item); } } } } Dictionary<string, Func<TA, object>> dicGet = new Dictionary<string, Func<TA, object>>(); Dictionary<string, Action<T, object>> dicSet = new Dictionary<string, Action<T, object>>(); foreach (var sourceInfo in sourceList) { //// 给对应(相同)的属性赋值 T resInfo = new T(); //// 给对应(相同)的属性赋值 foreach (PropertyInfo sourcePropertyInfo in sourcePropertyInfoList) { string sourcePropertyInfoName = sourcePropertyInfo.Name; if (resNamePro.ContainsKey(sourcePropertyInfoName)) { //// 获取数据源对应属性值 Func<TA, object> sourceProGet = null; if (dicGet.ContainsKey(sourcePropertyInfoName)) { sourceProGet = dicGet[sourcePropertyInfoName]; } else { sourceProGet = sourcePropertyInfo.BuildGetLambda<TA>(); dicGet[sourcePropertyInfoName] = sourceProGet; } var sourceProValue = sourceProGet(sourceInfo); //////// 给返回的对象相同属性赋值 Action<T, object> fieldSetter = null; if (dicSet.ContainsKey(sourcePropertyInfoName)) { fieldSetter = dicSet[sourcePropertyInfoName]; } else { fieldSetter = resNamePro[sourcePropertyInfoName].BuildSetLambda<T>(); dicSet[sourcePropertyInfoName] = fieldSetter; } fieldSetter(resInfo, sourceProValue); } } resList.Add(resInfo); } } } #endregion #region 对象值映射赋值(属性名称根据被指映射) /// <summary> /// 对象值映射赋值(属性名称根据被指映射) /// </summary> /// <typeparam name="T">需要赋值的对象:不能为空</typeparam> /// <typeparam name="TA">数据源:不能为空</typeparam> /// <param name="sourceInfo">数据源</param> /// <param name="resInfo">需要赋值的对象</param> public static T MappingTo<T, TA>(this TA sourceInfo) where T : class, new() where TA : class, new() { if (sourceInfo == null) { return null; } T resInfo = new T(); Type sourceType = typeof(TA); Type resType = typeof(T); //// 获取数据源public属性集合 PropertyInfo[] sourcePropertyInfoList = sourceType.GetProperties(); if (sourcePropertyInfoList != null) { //// 获取返回的对象的共有属性的名称集合,数据源不存在的不需要做赋值 var resProList = resType.GetProperties(); Dictionary<string, PropertyInfo> resNameProDic = new Dictionary<string, PropertyInfo>(); if (resProList != null) { foreach (var item in resProList) { var isIgnore = item.IsDefined(typeof(IgnoreAttribute), false); if (!isIgnore) { string resProName = item.Name; var mappingName = item.GetCustomAttribute<MappingNameAttribute>()?.MappingName; if (string.IsNullOrWhiteSpace(mappingName)) { resNameProDic.Add(resProName, item); } else { resNameProDic.Add(mappingName, item); } } } } //// 给对应(相同)的属性赋值 foreach (PropertyInfo sourcePropertyInfo in sourcePropertyInfoList) { string sourcePropertyInfoName = sourcePropertyInfo.Name; if (resNameProDic.ContainsKey(sourcePropertyInfoName)) { //// 获取数据源对应属性值 object sourceProValue = sourcePropertyInfo.GetValue(sourceInfo, null); //// 给返回的对象相同属性赋值 FillProValue(resInfo, sourcePropertyInfo, resNameProDic[sourcePropertyInfoName], sourceProValue); } } } return resInfo; } #endregion #region 对象值映射赋值(属性名称根据被指映射) /// <summary> /// 对象值映射赋值(属性名称根据被指映射) /// </summary> /// <typeparam name="T">需要赋值的对象:不能为空</typeparam> /// <typeparam name="TA">数据源:不能为空</typeparam> /// <param name="sourceList">数据源</param> /// <param name="resInfo">需要赋值的对象</param> public static List<T> MappingToList<T, TA>(this List<TA> sourceList) where T : class, new() where TA : class, new() { if (sourceList == null) { return null; } List<T> resList = new List<T>(); Type sourceType = typeof(TA); Type resType = typeof(T); //// 获取数据源public属性集合 PropertyInfo[] sourcePropertyInfoList = sourceType.GetProperties(); if (sourcePropertyInfoList != null) { //// 获取返回的对象的共有属性的名称集合,数据源不存在的不需要做赋值 var resProList = resType.GetProperties(); Dictionary<string, PropertyInfo> resNamePro = new Dictionary<string, PropertyInfo>(); if (resProList != null) { foreach (var item in resProList) { var isIgnore = item.IsDefined(typeof(IgnoreAttribute), false); if (!isIgnore) { string resProName = item.Name; var mappingName = item.GetCustomAttribute<MappingNameAttribute>()?.MappingName; if (string.IsNullOrWhiteSpace(mappingName)) { resNamePro.Add(resProName, item); } else { resNamePro.Add(mappingName, item); } } } } foreach (var sourceInfo in sourceList) { //// 给对应(相同)的属性赋值 T resInfo = new T(); //// 给对应(相同)的属性赋值 foreach (PropertyInfo sourcePropertyInfo in sourcePropertyInfoList) { string sourcePropertyInfoName = sourcePropertyInfo.Name; if (resNamePro.ContainsKey(sourcePropertyInfoName)) { //// 获取数据源对应属性值 object sourceProValue = sourcePropertyInfo.GetValue(sourceInfo, null); //// 给返回的对象相同属性赋值 FillProValue(resInfo, sourcePropertyInfo, resNamePro[sourcePropertyInfoName], sourceProValue); } } resList.Add(resInfo); } } return resList; } #endregion #region 对象值映射赋值(属性名称根据被指映射) /// <summary> /// 对象值映射赋值(属性名称根据被指映射) /// </summary> /// <typeparam name="T">需要赋值的对象:不能为空</typeparam> /// <typeparam name="TA">数据源:不能为空</typeparam> /// <param name="sourceList">数据源</param> /// <param name="resInfo">需要赋值的对象</param> public static List<T> MappingToListFunc<T, TA>(this List<TA> sourceList) where T : class, new() where TA : class, new() { if (sourceList == null) { return null; } List<T> resList = new List<T>(); Type sourceType = typeof(TA); Type resType = typeof(T); //// 获取数据源public属性集合 PropertyInfo[] sourcePropertyInfoList = sourceType.GetProperties(); if (sourcePropertyInfoList != null) { //// 获取返回的对象的共有属性的名称集合,数据源不存在的不需要做赋值 var resProList = resType.GetProperties(); Dictionary<string, PropertyInfo> resNamePro = new Dictionary<string, PropertyInfo>(); if (resProList != null) { foreach (var item in resProList) { var isIgnore = item.IsDefined(typeof(IgnoreAttribute), false); if (!isIgnore) { string resProName = item.Name; var mappingName = item.GetCustomAttribute<MappingNameAttribute>()?.MappingName; if (string.IsNullOrWhiteSpace(mappingName)) { resNamePro.Add(resProName, item); } else { resNamePro.Add(mappingName, item); } } } } Dictionary<string, Func<TA, object>> dicGet = new Dictionary<string, Func<TA, object>>(); Dictionary<string, Action<T, object>> dicSet = new Dictionary<string, Action<T, object>>(); foreach (var sourceInfo in sourceList) { //// 给对应(相同)的属性赋值 T resInfo = new T(); //// 给对应(相同)的属性赋值 foreach (PropertyInfo sourcePropertyInfo in sourcePropertyInfoList) { string sourcePropertyInfoName = sourcePropertyInfo.Name; if (resNamePro.ContainsKey(sourcePropertyInfoName)) { //// 获取数据源对应属性值 Func<TA, object> sourceProGet = null; if (dicGet.ContainsKey(sourcePropertyInfoName)) { sourceProGet = dicGet[sourcePropertyInfoName]; } else { sourceProGet = sourcePropertyInfo.BuildGetLambda<TA>(); dicGet[sourcePropertyInfoName] = sourceProGet; } var sourceProValue = sourceProGet(sourceInfo); //////// 给返回的对象相同属性赋值 Action<T, object> fieldSetter = null; if (dicSet.ContainsKey(sourcePropertyInfoName)) { fieldSetter = dicSet[sourcePropertyInfoName]; } else { fieldSetter = resNamePro[sourcePropertyInfoName].BuildSetLambda<T>(); dicSet[sourcePropertyInfoName] = fieldSetter; } fieldSetter(resInfo, sourceProValue); } } resList.Add(resInfo); } } return resList; } #endregion #region 比较--两个类型一样的实体类对象的值 /// 比较--两个类型一样的实体类对象的值 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="oneT"></param> /// <param name="twoT"></param> /// <returns>不一样内容的名称和值的差异</returns> public static string CompareType<T>(T oneT, T twoT) { string strFALSE = "FALSE"; string result = string.Empty;//两个类型作比较时使用,如果有不一样的就false Type typeOne = oneT.GetType(); Type typeTwo = twoT.GetType(); //如果两个T类型不一样 就不作比较 if (!typeOne.Equals(typeTwo)) { return strFALSE; } PropertyInfo[] pisOne = typeOne.GetProperties(); //获取所有公共属性(Public) PropertyInfo[] pisTwo = typeTwo.GetProperties(); //如果长度为0返回false if (pisOne.Length <= 0 || pisTwo.Length <= 0) { return strFALSE; } //如果长度不一样,返回false if (!(pisOne.Length.Equals(pisTwo.Length))) { return strFALSE; } //遍历两个T类型,遍历属性,并作比较 for (int i = 0; i < pisOne.Length; i++) { //获取属性名 string oneName = pisOne[i].Name; string twoName = pisTwo[i].Name; //获取属性的值 object oneValue = pisOne[i].GetValue(oneT, null); object twoValue = pisTwo[i].GetValue(twoT, null); if (oneName.Equals(twoName)) { //值不同的类型显示不同内容 bool flag = (oneValue == null && twoValue == null) || ((oneValue != null && twoValue != null) && (oneValue.Equals(twoValue))); if (!flag) { if (string.IsNullOrEmpty(result)) { result = string.Format("{0}: {1} -> {2}", oneName, oneValue, twoValue); } else { result += string.Format("; {0}: {1} -> {2}", oneName, oneValue, twoValue); } } } else { result = strFALSE; break; } } return result; } #endregion #region 私有方法 /// <summary> /// 给属性赋值,类型不一致转换为对应类型 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="resObj">返回的对象</param> /// <param name="sourceProperty">数据源属性</param> /// <param name="resProperty">被赋值的属性</param> /// <param name="sourcevalue">数据源属性值</param> private static void FillProValue<T>(T resObj, PropertyInfo sourceProperty, PropertyInfo resProperty, object sourcevalue) { if (sourceProperty.PropertyType != resProperty.PropertyType) { if (!resProperty.PropertyType.IsGenericType) { var newValue = string.IsNullOrEmpty(sourcevalue?.ToString()) ? null : Convert.ChangeType(sourcevalue, resProperty.PropertyType); //非泛型 resProperty.SetValue(resObj, newValue, null); } else { //泛型Nullable<> Type genericTypeDefinition = resProperty.PropertyType.GetGenericTypeDefinition(); if (genericTypeDefinition == typeof(Nullable<>)) { var newValue = string.IsNullOrEmpty(sourcevalue?.ToString()) ? null : Convert.ChangeType(sourcevalue, Nullable.GetUnderlyingType(resProperty.PropertyType)); resProperty.SetValue(resObj, newValue, null); } } } else { resProperty.SetValue(resObj, sourcevalue, null); } } /// <summary> /// 属性取值,拼装lambda表达式 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="properInfo">取值的属性</param> /// <returns></returns> private static Func<T, object> BuildGetLambda<T>(this PropertyInfo properInfo) { //// 获取属性的对象类型 var targetType = properInfo.DeclaringType; //// 定义属性的对象别名 t var exinstance = Expression.Parameter(targetType, "t"); //// t.xxx var lambdaBody = Expression.MakeMemberAccess(exinstance, properInfo); //// 值转换为object类型 var dataConvertToObject = Expression.Convert(lambdaBody, typeof(object)); //// 定义lambda表达式并预编译 var resLambda = Expression.Lambda<Func<T, object>>(dataConvertToObject, exinstance); return resLambda.Compile(); } /// <summary> /// 属性赋值、拼装lambda表达式 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="properInfo">赋值的属性</param> /// <returns></returns> private static Action<T, object> BuildSetLambda<T>(this PropertyInfo properInfo) { var targetType = properInfo.DeclaringType; var resParm = Expression.Parameter(targetType, "t"); var resBody = Expression.MakeMemberAccess(resParm, properInfo); var sourceParm = Expression.Parameter(typeof(object), "p"); var sourceParmConvertedValue = Expression.Convert(sourceParm, properInfo.PropertyType); var lambdaBody = Expression.Assign(resBody, sourceParmConvertedValue); var resLambda = Expression.Lambda<Action<T, object>>(lambdaBody, resParm, sourceParm); return resLambda.Compile(); } #endregion }
public class MappingNameAttribute : System.Attribute { /// <summary> /// 构造函数 /// </summary> /// <param name="mappingName">由对应的属性映射</param> public MappingNameAttribute(string mappingName ) { this.MappingName = mappingName; } /// <summary> /// 数据源属性名称 /// </summary> public string MappingName { get; set; } }
public class IgnoreAttribute : System.Attribute { /// <summary> /// 构造函数 /// </summary> /// <param name="isIgnore">是否忽略</param> public IgnoreAttribute(bool isIgnore=true) { IsIgnore = isIgnore; } /// <summary> /// 是否忽略 /// </summary> public bool IsIgnore { get; set; } }
/// <summary> /// 被赋值对象 /// </summary> public class demo2 { [Ignore] public int? a { get; set; }
[MappingName("ba")] public long? b { get; set; } public string c { get; set; } }