`

c# - expression tree and lambda - serie 1

    博客分类:
  • C#
c# 
阅读更多

In this post, we are going to discuss the topic on the Expression Tree and Delegate and Lambda, we are going to go through from simple expresison, then expression converted to delegate (lambda), and then we shape up/build up to a more complicated Expression Tree example and we compare it with its equivalent Lambda expression, later we shows why behind Expression Tree since we have the lambda expresion which has hte nice compile time check.

Code as Data

Code as Data is a long existed idea. But it hasn't bee used much in popular programming language. Expression Tree in .NET provides an abstract way of representing the code as a tree of objects. It's like COdeDOM but operate at a slightly higher level. The primary use of Expression tree is in LINQ and you can custom Expression to enable code execution in another end (or even language)

 

Expression Trees

The namespace in question is "System.Linq.Expression" , of all the classes that is contained in this namespace, Expression is the one that you may use most. 

 

Build a  simple expression tree

Let's first see an simple example of Building a exprssion tree

 

public static void ExploratoryExample()
    {
      Expression firstArg = Expression.Constant(2);
      Expression secondArg = Expression.Constant(3);
      Expression add = Expression.Add(firstArg, secondArg);
      Console.WriteLine(add); // this will evaluation the expression tree and does not execute the expression treee, it will print some string representation of the Linq Expression Tree 
                              // something like (1 + 2)
      
    }
 

It does almost trivial, it creates two Constant Expression and then made a call Expresion to glue the two together, Graphical representaion is as follow

 



 

In the Expression class, there are two properties 

Type: the .NET type of the evaluated Expression

NodeType: returns the kind of expression represented , as a member of ExpressoinType enumeration,with values such as LessThan....


 As you already know, we have build the ExpressionTree, but we can do barely anything with it, except, Expression has a Compile method which will turnst the Tree representaion of the expresion into executable code piece - a delegate.  Below shows how.

 

 

    public static void ExploratoryExample()
    {
      // build expression tree as above
      // ...
      Func<int> compiled = Expression.Lambda<Func<int>>(add).Compile(); // Lambda expression can compiled, and once compiled 
                                                                        // you can execute it 
      Console.WriteLine("compiled() = {0}", compiled());
    }

 

Now, you will get 5 if you execute the compiled delegate (Func<T> in this case)...

Converting a expression to a expression tree

So this is the other way around of the conversion, and it has  a lot of use implicaiton, suppose that you have some code (which is static checked and compiled by the Compiler) and you can convert that readily to expression tree. 

 

A very eimple way of doing that is as follow 

 

 

      // initialize a expression with a delegate
      // initialization as the conversion
      Expression<Func<int>> returns5 = () => 5;
      // you can compile the Expression back to lambda/delegate, as before 
      Func<int> compiled = returns5.Compile();
      Console.WriteLine("compiled() = {0}", compiled());

However, the conversion has limitation. In example 

 

 

  • You cannot convert a block of statement (even just one return statement), only single expression is supported
  • The expression cannot have assignment 

but the list is not exhausted. You will find more at compile time when make such attempt.

 

To get into details how things works, let see a more complicated expression tree example .Here is the lambda expression code. 

 

 

      Expression<Func<string, string, bool>> expression = (x, y) => x.StartsWith(y);

      var compiled = expression.Compile();

      Console.WriteLine(compiled("First", "Second"));
      Console.WriteLine(compiled("First", "Fir"));
 

 now let's try to build the expression that matches the code above. This is what we get. 

 

 

MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
      var target = Expression.Parameter(typeof(string), "x"); // ((string)x).Method(...)
      var methodArg = Expression.Parameter(typeof(string), "y"); // x.Method((string) y)
      Expression[] methodArgs = new[] { methodArg };             // methods args -- composite -->* methodArg


      Expression call = Expression.Call(target, method, methodArgs); // x.StartsWith(y)
      var lambdaParamters = new[] { target, methodArg };             // (x, y) -- (target, methodArgs) -- (arg1, arg2) => ...

      // it is difficult to figure out the argument types
      //var lambda = Expression.Lambda(call, methodArgs);
      // so you would probably indicate what is the type of the Lambda expression
      var lambda = Expression.Lambda<Func<string, string, bool>> (call, lambdaParamters);

      var compiled = lambda.Compile();
      Console.WriteLine("First", "Second");
      Console.WriteLine("First", "Fir");

 

A bit chunky, let's see the Expresion tree in its Graphic representation.  See below.

 


 

HINT, you can visualize the Expression Tree from the Text Visualizer. 

 

Expression Tree at the heart of LINQ.

Without lambda expresison, Expression Tree would have little value. They'd be an alternative to CodeDOM.

 

It is also ture for the reverse to a limited extent: without expression trees, lambda expression would certainmly be less useful. HAVing a more compact way of creating delegate would be welcome, and hte shift towards a more functinal development model would still be viable. Lambda expression are particular effective when combined with extension methods. But with expresion tree in the picture as well, things get a lot more interesting. 

 

Lambda expression provide:

Compile-check

Expression Tree provides:

abstract the execution model away from the desired logic. 

 

LINQ to SQL is good example of combination of Lamdba Expression and Expression Tree.


 

  • 大小: 32.8 KB
  • 大小: 12.6 KB
  • 大小: 22.2 KB
分享到:
评论

相关推荐

    Apress - Java Closures and Lambda.2015

    ### Apress - Java Closures and Lambda (2015):关键知识点解析 #### 引言 本书《Apress - Java Closures and Lambda》聚焦于Java 8中的新特性——闭包(Closures)和Lambda表达式。这些新功能不仅为Java语言带来...

    C# sql-linq-lambda

    根据给定文件中的标题、描述、标签以及部分内容,我们可以总结出以下有关C#中的SQL、LINQ和Lambda表达式之间的转换知识点。 ### C#中的SQL、LINQ与Lambda表达式的对比 #### 1. 基础查询 **SQL:** ```sql SELECT * ...

    sqs-to-lambda-via-lambda, 向Lambda函数交付SQS队列项( 使用 Lambda ).zip

    sqs-to-lambda-via-lambda, 向Lambda函数交付SQS队列项( 使用 Lambda ) 到 Lambda ( 通过 Lambda )当前没有用于Lambda的本机SQS事件源。 这种情况很糟糕。你可以运行类似于但是需要运行一个实例,谁想这样做。?运行...

    C#将Lambda表达式转成Sql语句

    在C#中,我们可以使用`IQueryable&lt;T&gt;`接口的扩展方法来构建这些查询,这些方法在内部会将Lambda表达式转换为表达式树(Expression Tree)。 表达式树是.NET框架中的一种类型,表示可执行的代码的抽象语法树。它们是...

    PyPI 官网下载 | mypy-boto3-lambda-1.17.48.0.tar.gz

    《PyPI官网下载的mypy-boto3-lambda-1.17.48.0.tar.gz:Python库解析》 PyPI(Python Package Index)是Python开发者们分享和获取Python软件包的主要平台。资源“mypy-boto3-lambda-1.17.48.0.tar.gz”正是源自这个...

    PyPI 官网下载 | mypy-boto3-lambda-1.10.39.2.tar.gz

    标题中的“PyPI官网下载 | mypy-boto3-lambda-1.10.39.2.tar.gz”表明这是一个从Python Package Index (PyPI) 官方网站上下载的软件包,名为“mypy-boto3-lambda”。这个软件包的版本是1.10.39.2,且其格式为tar.gz...

    PyPI 官网下载 | mypy-boto3-lambda-1.12.12.0.tar.gz

    《PyPI官网下载:mypy-boto3-lambda-1.12.12.0.tar.gz详析》 PyPI(Python Package Index)是Python开发者的重要资源库,它提供了大量的Python库,使得开发者能够方便地下载、安装和分享Python项目。在本篇文章中,...

    PyPI 官网下载 | mypy-boto3-lambda-1.17.88.post1.tar.gz

    《PyPI官网下载:mypy-boto3-lambda-1.17.88.post1.tar.gz——Python库解析》 PyPI(Python Package Index)是Python开发者们共享和分发软件包的主要平台,它是Python生态系统的核心组成部分。在这个平台中,我们...

    C# - C# 10.0 中的 Lambda 改进

    C# 10.0 对 lambda 表达式进行了多项改进,使其更加强大和灵活。这些增强功能包括能够为 lambda 表达式提供自然类型以及将方法组转换为委托,从而提高代码的可读性。以下是如何利用这些 lambda 改进:Lambda 的自然...

    一份易上手的C# Lambda表达式入门学习资料

    C# Lambda表达式入门学习资料 本文旨在为新手提供易于理解的C# Lambda表达式入门学习资料,帮助读者快速掌握Lambda表达式的基础知识和应用场景。 Lambda表达式是什么? -------------------- Lambda表达式是一种...

    PyPI 官网下载 | mypy-boto3-lambda-1.17.78.tar.gz

    标题中的“PyPI 官网下载 | mypy-boto3-lambda-1.17.78.tar.gz”指的是在Python的包索引服务(Python Package Index)官方网站上下载的一个名为“mypy-boto3-lambda”的软件包,版本号为1.17.78,格式为tar.gz压缩...

    Python库 | mypy-boto3-lambda-1.17.58.0.tar.gz

    标题中的"mypy-boto3-lambda-1.17.58.0.tar.gz"是一个针对Python开发的库,这个库集成了mypy、boto3和Lambda相关的功能。让我们详细了解一下这些关键组成部分。 **mypy**: mypy是Python的一个静态类型检查工具。在...

    aws-lambda-go-event, AWS Lambda事件源的类型定义.zip

    aws-lambda-go-event, AWS Lambda事件源的类型定义 eawsy/aws-lambda-go-eventAWS Lambda事件源的类型定义和帮助器。 使用 ,让你无需提供或者管理服务器即可运行代码。 使用 eawsy/aws-lambda-go-shi

    PyPI 官网下载 | mypy-boto3-lambda-1.18.13.tar.gz

    《PyPI官网下载的mypy-boto3-lambda-1.18.13.tar.gz:深入了解Python库的构建与使用》 PyPI(Python Package Index)是Python开发者的重要资源库,它为全球的Python开发者提供了众多开源软件包,便于他们进行项目...

    dynamodb-lambda-autoscale, 使用Lambda实现自动缩放 DynamoDB.zip

    dynamodb-lambda-autoscale, 使用Lambda实现自动缩放 DynamoDB dynamodb-lambda-autoscale使用 AWS Lambda函数 自动缩放 AWS DynamoDB5 分钟设置过程无服务器设计通过配置样式实现灵活的代码自动缩放表和全局二级...

    开源项目-mtojek-aws-lambda-go-proxy.zip

    开源项目-mtojek-aws-lambda-go-proxy.zip,mtojek/aws-lambda-go-proxy: Pass Lambda events to the application running on your machine | Debug real traffic locally | Forget about redeployments

    Python库 | mypy-boto3-lambda-1.17.72.tar.gz

    这里我们关注的是一个名为“mypy-boto3-lambda-1.17.72.tar.gz”的压缩包,它包含了Python库相关的资源。这个库特别针对了AWS(Amazon Web Services)的Lambda服务和Boto3库的类型检查。 首先,让我们了解一下Boto3...

    Ansible-chrome-aws-lambda.zip

    Ansible-chrome-aws-lambda.zip,用于aws lambda和google云功能的chrome aws lambda二进制文件,ansible是一个简单而强大的自动化引擎。它用于帮助配置管理、应用程序部署和任务自动化。

    VS2010轻松学习C#-从零到深入-天轰穿.NET4趣味编程视频教程_第26讲:深入委托

    在本节“VS2010轻松学习C# - 从零到深入 - 天轰穿.NET4趣味编程视频教程”的第26讲中,我们将深入探讨C#中的一个重要概念——委托。委托在C#中扮演着事件处理和回调函数的角色,是实现面向对象编程中的多态性和异步...

    Python库 | mypy-boto3-lambda-1.17.104.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:mypy-boto3-lambda-1.17.104.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

Global site tag (gtag.js) - Google Analytics