通过编译lambda表达式来创建实例(可在反射时候用,效率比反射高一些)
原文地址:https://rogerjohansson.blog/2008/02/28/linq-expressions-creating-objects/
据说编译lambda创建实例是比反射快。实际测试了一下,循环创建10,000次花的时间差不多,创建1,000,000,反射大概十几秒,lambda不到1秒。
实际使用应该没什么影响,因为一般不会出现大量创建实例的场景。不过创建生成lambda的代码还是可以学习下的。
- class Program
- {
- static void Main(string[] args)
- {
- var type = typeof(List<int>);
- var ctor = type.GetConstructor(Type.EmptyTypes);
- //使用Activator
- var list1 = Activator.CreateInstance(type);
- //使用ObjectActivator
- var activator = GetActivator<List<int>>(ctor);
- var list = activator.Invoke();
- Console.ReadKey();
- }
- public delegate T ObjectActivator<out T>(params object[] args);
- public static ObjectActivator<T> GetActivator<T>(ConstructorInfo ctor)
- {
- ParameterInfo[] paramsInfo = ctor.GetParameters();
- //create a single param of type object[]
- ParameterExpression param = Expression.Parameter(typeof(object[]), "args");
- Expression[] argsExp = new Expression[paramsInfo.Length];
- //pick each arg from the params array
- //and create a typed expression of them
- for (int i = ; i < paramsInfo.Length; i++)
- {
- Expression index = Expression.Constant(i);
- Type paramType = paramsInfo[i].ParameterType;
- Expression paramAccessorExp = Expression.ArrayIndex(param, index);
- Expression paramCastExp = Expression.Convert(paramAccessorExp, paramType);
- argsExp[i] = paramCastExp;
- }
- //make a NewExpression that calls the
- //ctor with the args we just created
- NewExpression newExp = Expression.New(ctor, argsExp);
- //create a lambda with the New
- //Expression as body and our param object[] as arg
- LambdaExpression lambda = Expression.Lambda(typeof(ObjectActivator<T>), newExp, param);
- //compile it
- ObjectActivator<T> compiled = (ObjectActivator<T>)lambda.Compile();
- return compiled;
- }
- }
通过编译lambda表达式来创建实例(可在反射时候用,效率比反射高一些)的更多相关文章
- Lambda 表达式递归用法实例
注意: 使用Lambda表达式会增加额外开销,但却有时候又蛮方便的. Windows下查找子孙窗口实例: HWND FindDescendantWindows(HWND hWndParent, LPC ...
- lambda表达式快速创建
Java 8十个lambda表达式案例 1. 实现Runnable线程案例 使用() -> {} 替代匿名类: //Before Java 8: new Thread(new Runnable( ...
- Java8 Lambda表达式详解手册及实例
先贩卖一下焦虑,Java8发于2014年3月18日,距离现在已经快6年了,如果你对Java8的新特性还没有应用,甚至还一无所知,那你真得关注公众号"程序新视界",好好系列的学习一下 ...
- 《C#本质论》读书笔记(12)委托和Lambda表达式
12.1.委托概述 12.1.2 委托的数据类型 为了减少重复代码数量,可以将比较方法作为参数传递给 BubbleSort()方法.此外,为了将方法作为参数传递,必须有一个能够标识方法的数据类型--也 ...
- 深入探索Java 8 Lambda表达式
2014年3月,Java 8发布,Lambda表达式作为一项重要的特性随之而来.或许现在你已经在使用Lambda表达式来书写简洁灵活的代码.比如,你可以使用Lambda表达式和新增的流相关的API,完 ...
- 深入浅出 Java 8 Lambda 表达式
摘要:此篇文章主要介绍 Java8 Lambda 表达式产生的背景和用法,以及 Lambda 表达式与匿名类的不同等.本文系 OneAPM 工程师编译整理. Java 是一流的面向对象语言,除了部分简 ...
- 转载:深入浅出 Java 8 Lambda 表达式
原文地址:http://viralpatel.net/blogs/Lambda-expressions-java-tutorial/ OneAPM for Java 能够深入到所有 Java 应用内部 ...
- 【Java8新特性】Lambda表达式基础语法,都在这儿了!!
写在前面 前面积极响应读者的需求,写了两篇Java新特性的文章.有小伙伴留言说:感觉Lambda表达式很强大啊!一行代码就能够搞定那么多功能!我想学习下Lambda表达式的语法,可以吗?我的回答是:没 ...
- Lambda表达式运行原理
目录 一.创建测试样例 二.利用Java命令编译分析 三.文末 JDK8引入了Lambda表达式以后,对我们写代码提供了很大的便利,那么Lambda表达式是如何运用简单表示来达到运行效果的呢?今天,我 ...
随机推荐
- Hibernate批量操作(二)
Hibernate提供了一系列的查询接口,这些接口在实现上又有所不同.这里对Hibernate中的查询接口进行一个小结. 我们首先来看一下session加载实体对象的过程:Session在调用数据库查 ...
- VIM的字符编码设置
vim 编码方式的设置和所有的流行文本编辑器一样,Vim 可以很好的编辑各种字符编码的文件,这当然包括UCS-2.UTF-8 等流行的 Unicode 编码方式.然而不幸的是,和很多来自 Linux ...
- python进阶(8):常用模块2+异常处理
前段时间讲了很多的模块应为当时面向对象没有讲有几个没有说今天补上,再说一个异常处理. 一.hashlib模块 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 摘要算法又称哈 ...
- 机器学习笔记——拉格朗日乘子法和KKT条件
拉格朗日乘子法是一种寻找多元函数在一组约束下的极值方法,通过引入拉格朗日乘子,可将有m个变量和n个约束条件的最优化问题转化为具有m+n个变量的无约束优化问题.在介绍拉格朗日乘子法之前,先简要的介绍一些 ...
- SpringMVC创建HelloWorld程序
1.IDE说明和依赖管理工具说明 开发工具:intellij idea 依赖管理使用:maven 2.创建maven工程 创建新的maven工程,并添加相应的文件夹,创建好的项目目录如下所示: 3.添 ...
- Markdown学习笔记(一) 基本的Markdown标签
Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式. Markdown的语法简洁明了.学习容易,而且功能比纯文本更强,因此有很多人用它写 ...
- 2015 Tencent 线上模拟测试题
第一题 下面的程序的输出结果是: A. 134122 B. 123412 C. 14302012 D. 143212 #include <iostream> using namespac ...
- 玩转JS系列之代码加载篇
从前我们这样写js <script type="text/javascript"> function a(){ console.log('a init');}funct ...
- .Net高级进阶,WebApi和MVC进行模型验证的时候,教你如何自由控制需要进行验证的字段?
现在,你有一个MVC架构的web项目,你要完成一个注册功能. 前台传了3个值到你的控制器,分别是账号.密码.邮箱. 如图:现在你要在控制器里面判断,账号名称.密码.邮箱不能为空,并且名称和密码不超过1 ...
- js中的访问器属性中的getter和setter函数实现数据双向绑定
嗯,之前在读js红宝书的时候,在对象那一章有介绍属性类型.第一种数据类型指的是数据属性,第二种是访问器属性.在初识vue的时候,其双向数据绑定也是基于访问器属性中的getter和setter函数原理来 ...