通过编译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 = 0; 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;
    }

}
时间: 2024-10-22 06:10:25

通过编译lambda表达式来创建实例(可在反射时候用,效率比反射高一些)的相关文章

Lambda 表达式递归用法实例

注意: 使用Lambda表达式会增加额外开销,但却有时候又蛮方便的. Windows下查找子孙窗口实例: HWND FindDescendantWindows(HWND hWndParent, LPCTSTR lpClassName, LPCTSTR lpWindowName) { HWND hFind = nullptr; UINT nCompare = 0; nCompare += (lpClassName != nullptr) ? 1 : 0; nCompare += (lpWindow

Java8 Lambda表达式详解手册及实例

先贩卖一下焦虑,Java8发于2014年3月18日,距离现在已经快6年了,如果你对Java8的新特性还没有应用,甚至还一无所知,那你真得关注公众号"程序新视界",好好系列的学习一下Java8的新特性.Lambda表达式已经在新框架中普通使用了,如果你对Lambda还一无所知,真得认真学习一下本篇文章了. 现在进入正题Java8的Lambda,首先看一下发音 ([?l?md?])表达式.注意该词的发音,b是不发音的,da发[d?]音. 为什么要引入Lambda表达式 简单的来说,引入La

Java8新增的Lambda表达式

Lambda表达式支持将代码块作为方法参数,Lambda表达式允许使用更简单的代码来创建只有一个抽象方法的接口(这种接口被称为函数式接口)的实例. 5.8.1 Lambda 表达式入门 Command.java package code; public interface Command { // 接口里定义的process()方法用于封装"处理行为" void process(int[] target); } ProcessArray.java package code; publi

Java8新特性学习笔记(一) Lambda表达式

没有用Lambda表达式的写法:  Comparator<Transaction> byYear = new Comparator<Transaction>() {             @Override            public int compare(Transaction o1, Transaction o2) {                return o1.getValue().compareTo(o2.getValue());             

java lambda表达式学习笔记

lambda是函数式编程(FP,functional program),在java8中引入,而C#很早之前就有了.在java中lambda表达式是'->',在C#中是‘=>’. 杜甫说:射人先射马,擒贼先擒王.学习一个库要学习它的入口类.lambda的入口类是Stream,一看Stream中的函数就会发现Function,Predicate等lambda元素. 一.几个概念     函数式接口 Functional Interface,除了static和default类型的方法外,只有一个函数

Java8函数式编程 (一) 数据流和lambda表达式

JDK 1.8中引入了函数式编程(functional programming,FP),如果您已习惯OOP,一定会感到困惑:什么是函数式编程?这样的编程模式有什么好处? 本文将通过简单的实例令读者对函数式编程有一个大体的了解. 我们知道OOP是以类为基础的,程序中必须首先抽象和定义class.那么FP创建的基础是什么?或者说在Java 8中,至少需要了解什么知识点才能实现基本的函数式编程呢? 本文将首先介绍在Java 8中使用FP所需的基本知识点: Lambda表达式 数据流 基本实例 Map<

Java SE 8 for the Really Impatient读书笔记——Java 8 Lambda表达式

1. lambda表达式的语法 语法十分简单:参数->主体 1.1 参数 可以是零个参数,一个参数,也可以是多个参数,参数可以指定类型,在编译器可以推导出参数类型的情况下,也可以省略参数类型. 两个参数的例子: (String first, String second)-> Integer.compare(first.length(), second.length()) 0个参数的例子: () -> { for (int i = 0; i < 1000; i++) doWork()

java8之lambda表达式(函数式接口)

在Java中有许多已有的接口都需要封装代码块,例如:Runnable或者Comparator.lambda表达式与这些接口是向后兼容的.对于只包含一个抽象方法的接口,你可以通过lambda表达式来创建该接口的对象,这种接口被称为函数式接口.注意:Java8中接口可以声明非抽象的方法. 为了演示函数式接口转换,我们以Arrays.sort方法为例.该方法的第二个参数需要一个Comparator接口(该接口只含有一个方法)的实例.接下来我们编写一个简单的lambda表达式: Arrays.sort(

Java函数式编程和lambda表达式

为什么要使用函数式编程 函数式编程更多时候是一种编程的思维方式,是种方法论.函数式与命令式编程的区别主要在于:函数式编程是告诉代码你要做什么,而命令式编程则是告诉代码要怎么做.说白了,函数式编程是基于某种语法或调用API去进行编程.例如,我们现在需要从一组数字中,找出最小的那个数字,若使用用命令式编程实现这个需求的话,那么所编写的代码如下: public static void main(String[] args) { int[] nums = new int[]{1, 2, 3, 4, 5,