c# 反射 對象賦值(map)


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; } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM