当前位置: 移动技术网 > IT编程>开发语言>.net > .NET core高性能对象转换示例代码

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

2018年08月08日  | 移动技术网IT编程  | 我要评论

虚无邪尊下载,身份证尾号是这数命中必有横财,静乐新闻

前言

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

示例代码

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

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

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)构造样例类

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) 调用

var a = new a
{
 id = 1,
 name = "张三",
 user = new c
 {
  id = 1,
  name = "李四"
 }
};<br>
b b = mapper<a, b>.map(a);//得到转换结果

4.性能测试

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万数据不带子类集结果

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

总结

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网