gpt4 book ai didi

.NET core高性能对象转换示例代码

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 24 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章.NET core高性能对象转换示例代码由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

前言 。

NET Core(开放源代码,跨平台,x-copy可部署等)有许多令人兴奋的方面,其中最值得称赞的就是其性能了。关于对象转换已经有不少轮子(AutoMapper,TinyMapper) .出于项目需要,手动造一个简单轮子。下面话不多说了,来一起看看详细的介绍吧.

示例代码 。

g>1.采用静态泛型类缓存,避免了拆箱装箱操作.

2.对于转换对象中有,字段名一样但是类型不一样的类时仍可以用 。

?
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
public static class Mapper<TSource, TTarget> where TSource : class where TTarget : class
  {
   public readonly static Func<TSource, TTarget> Map;
 
   static Mapper()
   {
    if (Map == null )
     Map = GetMap();
   }
 
   private static Func<TSource, TTarget> GetMap()
   {
    var sourceType = typeof (TSource);
    var targetType = typeof (TTarget);
 
    var parameterExpression = Expression.Parameter(sourceType, "p" );
    var memberInitExpression = GetExpression(parameterExpression, sourceType, targetType);
 
    var lambda = Expression.Lambda<Func<TSource, TTarget>>(memberInitExpression, parameterExpression);
    return lambda.Compile();
   }
 
   /// <summary>
   /// 根据转换源和目标获取表达式树
   /// </summary>
   /// <param name="parameterExpression">表达式参数p</param>
   /// <param name="sourceType">转换源类型</param>
   /// <param name="targetType">转换目标类型</param>
   /// <returns></returns>
   private static MemberInitExpression GetExpression(Expression parameterExpression, Type sourceType, Type targetType)
   {
    var memberBindings = new List<MemberBinding>();
    foreach (var targetItem in targetType.GetProperties().Where(x => x.PropertyType.IsPublic && x.CanWrite))
    {
     var sourceItem = sourceType.GetProperty(targetItem.Name);
 
     //判断实体的读写权限
     if (sourceItem == null || !sourceItem.CanRead || sourceItem.PropertyType.IsNotPublic)
      continue ;
 
     //标注NotMapped特性的属性忽略转换
     if (sourceItem.GetCustomAttribute<NotMappedAttribute>() != null )
      continue ;
 
     var propertyExpression = Expression.Property(parameterExpression, sourceItem);
 
     //判断都是class 且类型不相同时
     if (targetItem.PropertyType.IsClass && sourceItem.PropertyType.IsClass && targetItem.PropertyType != sourceItem.PropertyType)
     {
      if (targetItem.PropertyType != targetType) //防止出现自己引用自己无限递归
      {
       var memberInit = GetExpression(propertyExpression, sourceItem.PropertyType, targetItem.PropertyType);
       memberBindings.Add(Expression.Bind(targetItem, memberInit));
       continue ;
      }
     }
 
     if (targetItem.PropertyType != sourceItem.PropertyType)
      continue ;
 
     memberBindings.Add(Expression.Bind(targetItem, propertyExpression));
    }
    return Expression.MemberInit(Expression.New(targetType), memberBindings);
   }
  }

3.调用方法如下 。

 (1)构造样例类 。

?
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
public class A
{
  public int Id { get ; set ; }
  public string Name { get ; set ; }
  public C User { get ; set ; }
 
  /// <summary>
  /// 标注为notmapped特性时,不转换赋值
  /// </summary>
  [System.ComponentModel.DataAnnotations.Schema.NotMapped]
  public D UserA { get ; set ; }
 
}
 
public class B
{
  public int Id { get ; set ; }
  public string Name { get ; set ; }
  public D User { get ; set ; }<br data-filtered= "filtered" >
  public D UserA { get ; set ; }
}
 
public class C
{
  public int Id { get ; set ; }
  public string Name { get ; set ; }
}
 
public class D
{
  public int Id { get ; set ; }
  public string Name { get ; set ; }
}

  (2) 调用 。

?
1
2
3
4
5
6
7
8
9
10
11
var a = new A
{
  Id = 1,
  Name = "张三" ,
  User = new C
  {
   Id = 1,
   Name = "李四"
  }
};<br>
B b = Mapper<A, B>.Map(a); //得到转换结果

4.性能测试 。

?
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
var length = 10000000;
    var listA = new List<A>();
    for ( int i = 0; i < length; i++)
    {
     listA.Add( new A
     {
      Id = i,
      Name = "张三" ,
      User = new C
      {
       Id = i,
       Name = "李四"
      }
     });
    }
 
    var sw = Stopwatch.StartNew();
    for ( int i = 0; i < length; i++)
    {
     var item = listA[i];
     var b = new B
     {
      Id = item.Id,
      Name = item.Name,
      User = new D
      {
       Id = i,
       Name = "李四" ,
      }
     };
    }
    sw.Stop();
    Console.WriteLine($ "原生的时间:{sw.ElapsedMilliseconds}ms" );
 
    //表达式
    Mapper<A, B>.Map(listA[0]); //预先编译缓存
    sw.Restart();
    for ( int i = 0; i < length; i++)
    {
     Mapper<A, B>.Map(listA[i]);
    }
    sw.Stop();
    Console.WriteLine($ "表达式的时间:{sw.ElapsedMilliseconds}ms" );
 
    //AutoMapper
    AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<A, B>());
    sw.Restart();
    for ( int i = 0; i < length; i++)
    {
     var b = AutoMapper.Mapper.Map<B>(listA[i]);
    }
    sw.Stop();
    Console.WriteLine($ "AutoMapper时间:{sw.ElapsedMilliseconds}ms" );
 
    //TinyMapper
    TinyMapper.Bind<A, B>();
    sw.Restart();
    for ( int i = 0; i < length; i++)
    {
     var b = TinyMapper.Map<B>(listA[i]);
    }
    sw.Stop();
    Console.WriteLine($ "TinyMapper时间:{sw.ElapsedMilliseconds}ms" );
 
    Console.ReadLine();

5. 1000万数据不带子类集结果 。

.NET core高性能对象转换示例代码

6. 1000万数据带子类集结果  。

.NET core高性能对象转换示例代码

总结 。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我的支持.

原文链接:https://www.cnblogs.com/castyuan/archive/2018/07/09/9285101.html 。

最后此篇关于.NET core高性能对象转换示例代码的文章就讲到这里了,如果你想了解更多关于.NET core高性能对象转换示例代码的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com