1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
| /// <summary>
/// 生成表達式目錄樹。字典緩存
/// </summary>
public class ExpressionMapper
{
private static Dictionary<string, object> _dic = new Dictionary<string, object>();//緩存字典,緩存后的就是硬編碼所以性能高。
/// <summary>
/// 字典緩存表達式樹
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TDestination"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static TDestination Map<TSource, TDestination>(TSource source)
{
string key = $"funckey_{typeof(TSource).FullName}_{typeof(TDestination).FullName}";
if (!_dic.ContainsKey(key)) //如果該表達式不存在,則走一遍編譯過程
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "p");
List<MemberBinding> memberBindingList = new List<MemberBinding>();//表示綁定的類派生自的基類,這些綁定用于對新創建對象的成員進行初始化(vs的注解。太生澀了,我這樣的小白解釋不了,大家將就著看)
foreach (var item in typeof(TDestination).GetProperties()) //遍歷目標類型的所有屬性
{
MemberExpression property = Expression.Property(parameterExpression, typeof(TSource).GetProperty(item.Name));//獲取到對應的屬性
MemberBinding memberBinding = Expression.Bind(item, property);//初始化這個屬性
memberBindingList.Add(memberBinding);
}
foreach (var item in typeof(TDestination).GetFields())//遍歷目標類型的所有字段
{
MemberExpression property = Expression.Field(parameterExpression, typeof(TSource).GetField(item.Name));//獲取到對應的字段
MemberBinding memberBinding = Expression.Bind(item, property);//同上
memberBindingList.Add(memberBinding);
}
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TDestination)), memberBindingList.ToArray());//初始化創建新對象
Expression<Func<TSource, TDestination>> lambda = Expression.Lambda<Func<TSource, TDestination>>(memberInitExpression, parameterExpression);
_dic[key] = lambda.Compile(); //拼裝是一次性的
}
return ((Func<TSource, TDestination>)_dic[key]).Invoke(source);
}
}
|