写在开头,好奇从这里开始(当时让加查询条件,结果竟然是一句话来发挥神奇作用):

this.TestGrade = CriteriaHelper.NewObject<ITestCase, DtoTestCase>("测试等级", a => a.Grade);

1. 语法糖 Lambda

  在我看来,=>总是一个无敌可爱的符号。嗯,包括C语言里面的 -> 这个,它总像是在说“我指到这边,你看..”。

  找到了一张图[1],可以很好地说明lambda表达式,语法糖上的变化。

// 匿名方法,方法如何写应该是深入骨髓的哦:

          delegate(string text) { return text.Length; }

// Lambda表达式,作用与上行相同:

          (string text) => { return text.Length; }

// 还可以省略括号,这看起来就更像goes to“看到这里”的感觉了:

          (string text) => text.Length

// 让编译器推断参数类型:

          (text) => text.Length

// 还可以省略括号:

          text => text.Length
  注:Lambda表达式在去掉花括号时(即仅有一句时),其实是不带;符号的,一般加上的;是赋值语句规则的。

  下面有一个例子,一个让人觉得“怎么会有传方法这种这么神奇操作”的例子:

    class Film
{
public string Name { get; set; }
public int Year { get; set; }
} // Main函数:
var films = new List<Film>
{
new Film { Name = "Jaws", Year = },
new Film { Name = "Singing in the Rain", Year = },
new Film { Name = "Some like it Hot", Year = },
new Film { Name = "The Wizard of Oz", Year = },
new Film { Name = "American Beauty", Year = }
}; Action<Film> print = film => Console.WriteLine("Name = {0}, Year = {1}", film.Name, film.Year);
films.ForEach(print);
// Console.WriteLine("\r"); films.FindAll(film => film.Year < ).ForEach(print);
// Console.WriteLine("\r"); films.Sort((f1,f2) => f1.Name.CompareTo(f2.Name));
films.ForEach(print);

2. Lambda表达式与表达式树(Expression tree)

  在开启本节内容前,先捋清一下:

图2 [2]

  C#编译成公共中间语言(CIL或者IL,成果就是组件.dll文件),程序运行时再由实时编译器(Just in Time,JIT)转化为特定于CPU的语言。

2.1 表达式树

  表达式树就是对象构成的树,树中每个节点本身都是一个表达式。Expression类主要包括两个属性:

Type属性:表达式求值后的返回类型。

NodeType属性:返回所代表的表达式的种类,也是节点类型。

  表达式树,有很多不同类型的节点。

  例如可以这样想象:一个数是一个节点,一个运算符也是一个节点,那么一个简单的2+3表达式,就是有3个节点的树形关系。

    Expression firstArg = Expression.Constant();
Expression secondArg = Expression.Constant();
Expression add = Expression.Add(firstArg, secondArg); Console.WriteLine(add); // 打印出来的是表达式 (2 + 3)

  注意:“叶”表达式总是最先创建的。

  注意:Expression.Constant或者是Expression.Add类型都是继承于Expression的,这棵树的所有节点,都是Expression类型。

add

BinaryExpression

NodeType = Add

Type = System.Int32

firstArg

ConstantExpression

NodeType = Constant

Type = System.Int32

secondArg

ConstantExpression

NodeType = Constant

Type = System.Int32

图3 上例代码表达式树树形化表示

  继续上面的例子,既然打印出来的仅是表达式(2 + 3) ,那么能不能打印运行结果呢?

  可以想象一下,节点里面不管是数值或是运算符,其实对于表达式树来说,也就是多个节点或者少个节点的事。如果把节点当成没有实际意义的“圣诞树挂饰”(因为树上的节点“不干活”),那表达式树到底有什么意义?

  那句话是这样的,“没有Lambda表达式,表达式树几乎没有任何价值”。

  我算是有些明白,“code as data”是什么意思。没有数据,代码是惘然的。但是“叶子”有了,怎么让树“活过来”?微软提供的方式是:将表达式树编译成委托——既然有各种类型的节点,怎么不能有方法类型的节点呢。

    Expression leftArg = Expression.Constant();
Expression rightArg = Expression.Constant();
Expression add = Expression.Add(leftArg, rightArg); Func<int> compiled = Expression.Lambda<Func<int>>(add).Compile();
Console.WriteLine(compiled());

  C#当中Lambda表达式支持表达式树,不过还需要该节点使用Compile()方法(大概就是编译成对应的Func<T>类型,此方法涉及到System.Reflection.MethodInfo,这节内容放到后面来谈)。

   Expression<Func<int>> return5 = () => ;   // () => 5是一个Lambda表达式

   Func<int> compiled = return5.Compile();    // 把Lambda表达式转换成表达式树。
                            // (这种转换有限制,此处不详谈。)

2.2 Lambda表达式与LINQ

  LINQ(Language Integrated Query)是一种基于中间查询能够直接反馈到C#语言环境当中的技术。

  LINQ提供器的中心思想在于:从一个熟悉的源语言(比如C#)生成一个表达式树,将结果作为一个中间格式,再将其转换成目标平台上的本地语言(比如SQL)。

  LINQ to Objects方式是:使用含有Lambda表达式的C#查询代码,再由转化为相应的IL,在CLR中执行。

  LINQ to SQL方式:编译成使用表达式树IL,在执行时,动态执行sql语句(IL已经处理好怎么让LINQ to SQL提供器处理到本地语言)。

  ……

  除了LINQ to Objects和LINQ to SQL还有其他的数据查询方式,此处不展开。

==================================================================================

  下节内容:

  【C#基础】拥抱Lambda(1):表达式树与LINQ

注释:

[1]  Lambda语法简写

[2] 图源自 维基百科

[3] 此笔记主要参考 《深入理解C#》(第3版)Jon Skeet 著  姚琪琳 译

【C#进阶】拥抱Lambda(一)的更多相关文章

  1. 【C#进阶】拥抱Lambda(二)

    语言的设计,真的是挺有意思的.第一次看这个代码[1]时,旁人随口了一句"哇,好多实心句号". 当时马上一个想法是--怎么实现的?返回了对象,然后再调用方法?然后就放下了,后来发现, ...

  2. c#进阶之lambda表达式

    阅读之前,先确保对委托有基本的了解,传送门 c#进阶之浅析委托和事件. lambda表达式雏形第一步 在委托那篇文章,绑定的的方法都是具名函数,为了简化书写,可以换成匿名函数 public deleg ...

  3. Python 进阶 之 lambda 匿名函数

    lambda 是个匿名函数,通常用于简单判断或者处理,例如判断一个数的奇偶性,过滤字符串,逻辑运算等等. lambda表达式: >>>lambda x:x*x >>> ...

  4. Java基础进阶:内部类lambda重点摘要,详细讲解成员内部类,局部内部类,匿名内部类,Lambda表达式,Lambda表达式和匿名内部类的区别,附重难点,代码实现源码,课堂笔记,课后扩展及答案

    内部类lambda重点摘要 内部类特点: 内部类可以直接访问外部类,包括私有 外部类访问内部类必须创建对象 创建内部对象格式: 外部类.内部类 对象名=new外部类().new内部类(); 静态内部类 ...

  5. 理解和运用Java中的Lambda

    前提 回想一下,JDK8是2014年发布正式版的,到现在为(2020-02-08)止已经过去了5年多.JDK8引入的两个比较强大的新特性是Lambda表达式(下文的Lambda特指JDK提供的Lamb ...

  6. Python爬虫与数据分析之进阶教程:文件操作、lambda表达式、递归、yield生成器

    专栏目录: Python爬虫与数据分析之python教学视频.python源码分享,python Python爬虫与数据分析之基础教程:Python的语法.字典.元组.列表 Python爬虫与数据分析 ...

  7. Linq之Lambda进阶

    目录 写在前面 系列文章 带有标准查询运算符的Lambda Lambda中类型推断 Lambda表达式中变量作用域 异步Lambda 总结 写在前面 上篇文章介绍了Lambda的基本概念以及匿名方法, ...

  8. Python进阶之匿名函数(关键词lambda)

    匿名函数 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB"," ...

  9. 动态Lambda进阶一

    直接上代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using S ...

随机推荐

  1. vprintf 和 vsnpintf 的用法

    函数定义: int vprintf ( const char * format, va_list arg ); printf() and friends are for normal use. vpr ...

  2. Python3 List list()方法

    Python3 List list()方法  Python3 列表 描述 list() 方法用于将元组或字符串转换为列表. 注:元组与列表是非常类似的,区别在于元组的元素值不能修改,元组是放在括号中, ...

  3. MongoDB的数据类型(四)

    JSON JSON是一种简单的数据表示方式,它易于理解.易于解析.易于记忆.但从另一方面来说,因为只有null.布尔.数字.字符串.数组和对象这几种数据类型,所以JSON有一定局限性.例如,JSON没 ...

  4. 14-n皇后

    /*题目内容: 国际象棋中的皇后可以沿着水平线,垂直线,或者斜线前进,吃掉遇到的所有棋子,如果棋盘上有八个皇后,则这八个皇后如何相安无事的放置在棋盘上,1970年与1971年, E.W.Dijkstr ...

  5. discuz回贴通知插件实现-获取邮件内容

    //自定义钩子函数,命名:模块_函数名_output()或模块_函数名() //一个是模块执行完,模板输出前执行.一个是模块执行前 //post_reply_output函数会在所有post操作中都会 ...

  6. Spring框架的Bean管理的配置文件方式

    1. id属性和name属性的区别 * id -- Bean起个名字,在约束中采用ID的约束,唯一 * 取值要求:必须以字母开始,可以使用字母.数字.连字符.下划线.句话.冒号 id:不能出现特殊字符 ...

  7. 64bits access

    http://www.codicode.com/art/64_bit_version_of_microsoft_jet.aspx

  8. 面向对象设计模式纵横谈:Bridge 桥接模式(笔记记录)

    桥接模式是一个比较难理解的设计模式,设计和分析的时候也不容易把握,咱们听听“李建忠”老师是怎么来讲的.我们还是从演变的角度来说问题,一步一步的来把问题说清楚.先谈谈“抽象”和“实现”的关系. 抽象与实 ...

  9. geoserver中除了使用kml来查询数据以外,还可以使用csql或ecsql

    package com.geoserver; import java.io.IOException; import java.util.ArrayList; import java.util.Hash ...

  10. PS想象的力量无限大,设计师的脑洞无限大!

    我(nemanjasekulic)一直对魔法与科幻感兴趣,但是,现实中,它们并不存在.我所做的是尽量体现一切都是可能的,表达一种没有约束的理想概念. 编辑:千锋UI设计