//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有 // 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权 // CSDN博客:https://blog.csdn.net/qq_40374647 // 哔哩哔哩视频:https://space.bilibili.com/94253567 // Gitee源代码仓库:https://gitee.com/RRQM_Home // Github源代码仓库:https://github.com/RRQM // API首页:https://www.yuque.com/rrqm/touchsocket/index // 交流QQ群:234762506 // 感谢您的下载和使用 //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Reflection; namespace TouchSocket.Core { /// /// 映射数据 /// //[IntelligentCoder.AsyncMethodPoster(Flags = IntelligentCoder.MemberFlags.Public)] public static partial class Mapper { private static readonly ConcurrentDictionary> m_typeToProperty = new ConcurrentDictionary>(); /// /// 简单映射 /// /// /// /// /// public static TTarget Map(this object source, MapperOption option = default) where TTarget : class, new() { return (TTarget)Map(source, typeof(TTarget), option); } /// /// 简单映射 /// /// /// /// /// public static TTarget Map(this TTarget source, MapperOption option = default) where TTarget : class, new() { return (TTarget)Map(source, typeof(TTarget), option); } /// /// 简单映射 /// /// /// /// /// /// public static TTarget Map(this TSource source, MapperOption option = default) where TTarget : class, new() { return (TTarget)Map(source, typeof(TTarget), option); } /// /// 简单对象映射 /// /// /// /// /// public static object Map(this object source, Type targetType, MapperOption option = default) { return Map(source, Activator.CreateInstance(targetType), option); } /// /// 简单对象映射 /// /// /// /// /// public static object Map(this object source, object target, MapperOption option = default) { if (source is null) { return default; } var sourceType = source.GetType(); if (sourceType.IsPrimitive || sourceType.IsEnum || sourceType == TouchSocketCoreUtility.stringType) { return source; } var sourcePairs = m_typeToProperty.GetOrAdd(sourceType, (k) => { Dictionary pairs = new Dictionary(); var ps = k.GetProperties(BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var item in ps) { pairs.Add(item.Name, new Property(item)); } return pairs; }); var targetPairs = m_typeToProperty.GetOrAdd(target.GetType(), (k) => { Dictionary pairs = new Dictionary(); var ps = k.GetProperties(BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var item in ps) { pairs.Add(item.Name, new Property(item)); } return pairs; }); foreach (var item in sourcePairs) { if (item.Value.CanRead) { string pkey = item.Key; if (option != null && option.MapperProperties != null && option.MapperProperties.ContainsKey(pkey)) { pkey = option.MapperProperties[pkey]; } if (option?.IgnoreProperties?.Contains(pkey) == true) { continue; } if (targetPairs.TryGetValue(pkey, out Property property)) { if (property.CanWrite) { property.SetValue(target, item.Value.GetValue(source)); } } } } return target; } /// /// 映射List /// /// /// /// /// /// public static IEnumerable MapList(this IEnumerable list, MapperOption option = default) where T : class where T1 : class, new() { if (list is null) { throw new ArgumentNullException(nameof(list)); } List result = new List(); foreach (var item in list) { result.Add(Map(item, option)); } return result; } /// /// 映射List /// /// /// /// /// /// public static IEnumerable MapList(this IEnumerable list, MapperOption option = default) where T1 : class, new() { if (list is null) { throw new ArgumentNullException(nameof(list)); } List result = new List(); foreach (var item in list) { result.Add(Map(item, option)); } return result; } } }