面向对象设计——原来“Lambda表达式”是这样来的

在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法。 C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方法,作为编写内联代码的首选方式。

——MSDN

以上是来自MSDN中的话,可以看出声明委托的这样一个发展:命名方法→匿名方法→Lambda表达式。下面通过代码展示一下他们是如何进化的。

命名方法

对于更高层次的面象对象而言,委托是必须。那么,我们就以实现“求两个数中的最大数”为例看最原始的委托实现方式。

声明一个成员方法:

public int CompareTwoValue(int a, int b)
{
    if (a > b)
    {
        return a;
    }
    else
    {
        return b;
    }
}

再声明一个委托:

public delegate int deleMethod(int a,int b);

通过委托调用上面的成员方法。注意一点的是方法的参数类型和返回类型必须与委托的参数和返回类型相匹配。本例中成员方法和委托都是输入两个int值而输出一个int值。

public int Show()
{
    deleMethod max = new deleMethod(CompareTwoValue);    //实例化
    return max(5, 10);                                   //调用
}

匿名委托

也称作匿名方法,其实,这只是一种语法形式上的变化,因为编译的时候,还是要进行类型匹配的,那么对于上面的Show方法,我可以使用匿名委托的方式来表达。

<pre name="code" class="csharp">public int Show()
{
    deleMethod max = delegate(int a, int b)
    {
        if (a > b)
        {
            return a;
        }
        else
        {
            return b;
        }
    };
    return max(5, 10);
}

很显然,我们看不到命名的地方,通过匿名的方法,使语法形式上简便了,但觉得匿名委托在C#2.0中并没有实质性的用处,只有到3.0时,涉及到Lamda表达式时,才真正的有用处。

Lambda表达式

用Lamda表达式写上面的方法:

public int Show()
{
    Func<int, int, int> max = (a, b) =>
    {
        if (a > b)
        {
            return a;
        }
        else
        {
            return b;
        }
    };
    return max(5, 10);
}

Lamda表达式只是匿名委托的一种表现形式。可以很直观的看出,三种方式中,Lamda表达式编写的代码量最少。

由于我们已经注明max的类型是Func<int, int, int>,因此C#编译器可以明确地知道a和b都是int类型,于是我们就可以省下参数之前的类型信息。这个特性叫做“类型推演”,也就是指编译器可以自动知道某些成员的类型。请不要轻易认为这个小小的改进意义不大,事实上,您会发现Lambda表达式的优势都是由这一点一滴的细节构成的。那么我们再来一次改变:

Func<int, int, int> max = (a, b) => a > b ? a : b;

如果Lambda表达式的body是一个表达式(expression),而不是语句(statement)的话,那么它的body就可以省略大括号和return关键字。此外,如果Lambda表达式只包含一个参数的话,则参数列表的括号也可以省略,如下:

Func<int, bool> positive = a => a > 0;

如今的写法是不是非常简单?那么我们来看看,如果是使用delegate关键字来创建的话会成为什么样子:

Func<int, bool> positive = delegate(int a)
{
    return a > 0;
};

您马上就可以意识到,这一行和多行的区别,这几个关键字和括号的省略,会使得编程世界一下子变得大为不同。(当然,Lambda表达式也并不是可以完全替代delegate写法,例如带ref和out关键字的匿名方法,就必须使用.NET
2.0中的delegate才能构造出来了。)

总结

就一句话:既可以提高可读性,又能够减少代码数量,我实在找不出任何理由拒绝Lambda表达式。

时间: 2024-11-20 20:35:47

面向对象设计——原来“Lambda表达式”是这样来的的相关文章

通过字节码分析JDK8中Lambda表达式编译及执行机制

关于Lambda字节码相关的文章,很早之前就想写了,[蜂潮运动]APP 产品的后端技术,能快速迭代,除了得益于整体微服架构之外,语言层面上,也是通过Java8的lambda表达式的运用以及rxJava响应式编程框架,使代码更加简洁易维护,调用方式更加便捷.本文将介绍JVM中的方法调用相关的字节码指令,重点解析JDK7(JSR-292)之后新增的invokedynamic指令给lambda表达式的动态调用特性提供的实现机制,最后再探讨一下lambda性能方面的话题. 方法调用的字节码指令 在介绍i

[Java 8] 使用Lambda表达式进行设计

使用Lambda表达式进行设计 在前面的几篇文章中,我们已经见识到了Lambda表达式是如何让代码变的更加紧凑和简洁的. 这一篇文章主要会介绍Lambda表达式如何改变程序的设计,如何让程序变的更加轻量级和简洁.如何让接口的使用变得更加流畅和直观. 使用Lambda表达式来实现策略模式 假设现在有一个Asset类型是这样的: public class Asset { public enum AssetType { BOND, STOCK }; private final AssetType ty

Java语言编程学习之Lambda表达式设计和架构的原则[图]

Java语言编程学习之Lambda表达式设计和架构的原则[图]:大家都知道,Lambda表达式是对Java语言的一点简单改进,在JDK标准类库中,运行它的方式各种各样.但是大多数的Java代码都不是由开发JDK的程序猿写的,而是像我们这样的普通程序猿.很多人都会碰到过这样的情况:你实现了一个新功能或修复了一个缺陷,并且对自己的修改很满意.但其他人看了你的代码后--也许发生在代码审查环节,完全不买账!对于什么是好代码,什么是坏代码,存在分歧很正常!设计模式的改变设计模式是人们熟悉的另一种设计思想,

JDK8新特性01 Lambda表达式01_设计的由来

1.java bean public class Employee { private int id; private String name; private int age; private double salary; public Employee() { } public Employee(String name) { this.name = name; } public Employee(String name, int age) { this.name = name; this.a

Android Stutio中使用java8的Lambda表达式

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51532028 本文出自:[openXu的博客] 目录: 为什么要使用Lambda表达式 让Android Stutio支持Lambda 函数式接口Functional interfaces Lambda表达式的目标类型以及匹配 Lambda表达式语法 1 基础语法和语法简化 2 Lambda表达式的词法作用域 3 变量捕获 ??Java 8的一个大亮点是引入Lambda表达式,使用它设计的

1.1 为什么要使用lambda 表达式

第1章 lambda 表达式 1.2 lambda 表达式的语法 1.3 函数式接口 1.4 方法引用 1.5 构造器引用 1.6 变量作用域 1.7 默认方法 1.8 接口中的静态方法 练习 Java 作为一门面向对象的编程语言诞生于20 世纪90 年代,在当时,面向对象编程是软件开发的主流模式.在面向对象编程出现之前,也曾诞生过像Lisp 和Scheme 这样的函数式编程语言,但它们只活跃于学术圈中.最近,由于在并发和事件驱动(或者称"互动")编程中的优势,函数式编程又逐渐变得重要

Java 8 vs. Scala(一): Lambda表达式

[编者按]虽然 Java 深得大量开发者喜爱,但是对比其他现代编程语言,其语法确实略显冗长.但是通过 Java8,直接利用 lambda 表达式就能编写出既可读又简洁的代码.作者 Hussachai Puripunpinyo 的软件工程师,作者通过对比 Java 8和 Scala,对性能和表达方面的差异进行了分析,并且深入讨论关于 Stream API 的区别,本文由OneAPM 工程师编译整理. 数年等待,Java 8 终于添加了高阶函数这个特性.本人很喜欢 Java,但不得不承认,相比其他现

Java8新特性Stream API与Lambda表达式详解(1)

1 为什么需要Stream与Lambda表达式? 1.1  为什么需要Stream Stream作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 XML 解析的 Stream,也不是 Amazon Kinesis 对大数据实时处理的 Stream.Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利.高效的聚合操作(aggr

lambda表达式封装对数据库的查询

前言: 1.为什么要封装lambda表达式数据库查询,原因有一下几点: 1.1.在以往的开发中进行数据库表查询时,其实所需要的字段就是其中几个,但是在开发中,开发者往往习惯select * 进行查询,当数据多和用户量多时,查询的效率会降低. 1.2.在写查询where条件的时候,总是用string.format去拼接字符串,开发效率低. 1.3.代码不够优雅,代码中嵌套和多sql语句,如果是表字段发生改变时编译器检查不出来,代码出错的概率大. 1.4.本着 write less  do more