之前总结了委托这个困惑着大多初学者的概念,继续来学习匿名方法和lambda表达式

(1)我们之前写了这样一段代码

//自定义一个委托
public delegate int Expression(int a, int b);
class Program
{
static void Main(string[] args)
{
//(2)委托扩展
//Expression ex = Add;
//Calculate(ex, 25, 10);
Calculate(Add, , );
}
static int Add(int a, int b)
{
return a + b;
}
static int Divide(int a, int b)
{
return a / b;
}
static int subtract(int a, int b)
{
return a - b;
}
static int multiply(int a, int b)
{
return a * b;
}
static int GetAdd(int a, int b)
{
return a + b;
}
static void Calculate(Expression ex, int a, int b)
{
Console.WriteLine(ex(a, b) + "\n");
}
}

  我们既然之前说到已经把Calculate封装起来了,那么这里我们就把Calculate方法看成一个已经封装好了的方法(这里只是为了举例,并不是指Calculate方法真的已经完全封装好了),那么既然Calculate已经不能改了,那么四个加减乘除方法有什么可以优化的地方呢?,我们把a - b,a * b,a / b等等可以写的计算表达式写成不同的方法,而且还分别不同命名,这样做是不是有点过于“浪费”了勒,我们写这样四个方法真正要实现的目的就是能让四个方法传递到另一个方法的某一个语句块中被执行,这段要被传递的语句块有没有名字其实并不重要,那么这里就要引出一位今天的主人公了,他就是匿名方法,很多人刚接触这个概念时可能会一头雾水,而且大多教科书都喜欢把它放在委托的后面讲,就会觉得这个东西很神奇,其实匿名方法并没有那么复杂,不明白只是因为对这个概念生疏而已,或者说是人的惯性思维,我们在初学时都习惯了约定俗成的认为一个方法必须有名字,有参数,有返回值,其实语言的设计者再设计方法(有的语言也叫函数)的初衷就是增加代码的重用,使代码更灵活而已,不管是方法还是匿名方法,其本质都是一段执行语句,所以顾名思义,匿名方法就是没有名字的一方法,那方法是什么,你可以粗暴的理解为方法就是一段可以通过方法名来调用执行语句,那么匿名方法就是一段没有名字的执行语句,他们都是执行语句。说了这么多我来具体看一下,如何通过匿名方法实现上面的代码

//自定义一个委托
public delegate int Expression(int a, int b);
class Program
{
static void Main(string[] args)
{
//(3)匿名方法
Expression add = delegate (int a, int b) { return a + b; };
Expression subtract = delegate (int a, int b) { return a - b; };
Expression multiply = delegate (int a, int b) { return a * b; };
Expression divide = delegate (int a, int b) { return a / b; };
Calculate(add, , );
} //static int Add(int a, int b)
//{
// return a + b;
//}
//static int Divide(int a, int b)
//{
// return a / b;
//}
//static int subtract(int a, int b)
//{
// return a - b;
//}
//static int multiply(int a, int b)
//{
// return a * b;
//} static void Calculate(Expression ex, int a, int b)
{
Console.WriteLine(ex(a, b) + "\n");
}
}

  这里我们直接对Expression委托类型进行赋值,将四个匿名方法赋值给了Expression的实例,这样我们不必在为每种计算分别写不同的方法了,这样写看上去是不是比之前美观简洁了许多,但是实际代码并没有减少许多,我们可不可以有什么方法,直接写一个表达式传给Calculate方法呢?这里就要引入今天的另一个主角——lambda表达式,说到lambda表达式,你并不要害怕,其实lambda表达式并不是一个全新的概念,它只不过是升级了的匿名方法罢了,很多初学者看到lambda表达式,完全无法想象他与匿名方法,以及委托有什么关系,又会误认为它是一个全新的概念,其实并不是,它只不过是一段更为简洁的匿名方法罢了,也可以它只不过是一段更为简洁的执行语句罢了。下面我们就来通过代码来对比lambda表达式,匿名方法,以及方法+委托

(1)最原始的一种,定义方法,通过委托传递或调用方法

//自定义一个委托
public delegate int Expression(int a, int b);
class Program
{
static void Main(string[] args)
{
Expression ex = Add;
Calculate(ex, , );
//或者直接这样写
//Calculate(Add, 10, 25);
Console.ReadKey();
} static int Add(int a, int b)
{
return a + b;
}
static int Divide(int a, int b)
{
return a / b;
}
static int subtract(int a, int b)
{
return a - b;
}
static int multiply(int a, int b)
{
return a * b;
}
static void Calculate(Expression ex, int a, int b)
{
Console.WriteLine(ex(a, b) + "\n");
}
}

(2)第二种,也就是最上面写的那种,通过委托传递匿名方法

//自定义一个委托
public delegate int Expression(int a, int b);
class Program
{
static void Main(string[] args)
{
Expression add = delegate (int a, int b) { return a + b; };
Expression subtract = delegate (int a, int b) { return a - b; };
Expression multiply = delegate (int a, int b) { return a * b; };
Expression divide = delegate (int a, int b) { return a / b; };
Calculate(add, , );
} static void Calculate(Expression ex, int a, int b)
{
Console.WriteLine(ex(a, b) + "\n");
}
}

(2)第三种,进一步简化匿名方法,直接传递lambda表达式

    public delegate int Expression(int a, int b);
class Program
{
static void Main(string[] args)
{
Calculate((a, b) => a + b, , );
Calculate((a, b) => a - b, , );
Calculate((a, b) => a * b, , );
Calculate((a, b) => a / b, , );
} static void Calculate(Expression ex, int a, int b)
{
Console.WriteLine(ex(a, b) + "\n");
}
}

  可能你对第三部的写法还是有些不太明白,为什么(a, b) => a + b连参数类型和返回值都没有了,还是可以编译和执行,系统是如何知道这个表达式的参数类型和返回值的呢?这里我们在方法Calculate定义的时候第一个参数是Expression类型,所以我们既然已经在定义委托时已经规定了Expression的参数个数,参数类型,以及返回值类型,那么我们在写lambda表达式就不必在重复定义类型了,所以参数类型与返回值类型不用重复定义,只是需要注意到是参数个数,当lambda表达式只有一个参数时,表达式的”()“括号可以省略,无参和多参括号都不可以省。

  这就是从委托到lambda表达式一步步的演化,我们的理解也一步步的加深,其实这就是lambda表达式就是C#这门语言不断进化的产物,无论它怎样进化,变得多么简单,它最终的本质还是逃不过那几个字:一段可以被传递的执行语句

委托学习总结(二)匿名方法和lambda表达式的更多相关文章

  1. C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=.答案是6个Firs ...

  2. 写的非常好的文章 C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...

  3. (转)C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...

  4. [No0000134]C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...

  5. 【转】C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...

  6. C#学习之初步理解委托、事件、匿名方法和Lambda

    最经在学习LinqtoSql,然后扯到Lambda表达式,然后扯到匿名方法,然后扯到委托,最后扯到事件处理...后来发现对委托这个概念和事件处理这个过程理解得不是很清晰,遂得一下学习笔记.那里说得不对 ...

  7. c#委托中的匿名方法和lambda表达式

    一.一般委托方式 Func<int, int, int> AddMethodHander; public unName() { AddMethodHander += AddMethod; ...

  8. 匿名方法和Lambda表达式

    匿名方法本质上是一传递给委托的代码块,是使用委托的另一种方法. 规则: 1.匿名方法中不能使用跳转语句跳至次匿名方法的外部,反之亦然:匿名方法外部的跳转语句也不能跳转到匿名方法的内部: 2.在匿名方法 ...

  9. 匿名方法和Lambda 表达式

    Overview 当你使用委托的时候,有时候是否会感觉到略微有些麻烦,尽管委托已经极大的减少了我们的工作量,比如,有一个方法,只需要使用一次,仅仅是传递给委托,我们就要定义一次他,这未免太 " ...

随机推荐

  1. 自然语言处理--N-gram

    考虑一个语音识别系统,假设用户说了这么一句话:“I have a gun”,因为发音的相似,该语音识别系统发现如下几句话都是可能的候选:1.I have a gun. 2.I have a gull. ...

  2. 《深入理解Java虚拟机》目录

    第一部分 走进Java 第1章 走进Java   第二部分 自动内存管理机制 第2章 Java内存区域与内存溢出异常 2.2 运行时数据区域 2.3 HotSpot虚拟机对象探秘 第3章 垃圾收集器与 ...

  3. 数据序列化导读(2)[YAML]

    上一节讲了JSON, 这一节将介绍YAML.可以认为,YAML是JSON的超集,但是更加简单易用,适合人类阅读和书写. 1.  什么是YAML? YAML是YAML Ain't Markup Lang ...

  4. ConfigurationManager

    ConfigurationManager读取和写入 提供对客户端应用程序配置文件的访问 通过引入System.Configuration.dll可以用ConfigurationManager类来读取项 ...

  5. 【BI】资料收集

    从无到有--什么是BI 什么是BI(Business Intelligence) - @我爱菊花 - 博客园 http://www.cnblogs.com/jiesin/archive/2008/06 ...

  6. golang基础--细说defer

    defer 匿名函数特性 执行方式类似其它语言中的析构函数,在函数体执行结束后按照调用顺序的相反顺序逐个执行 //执行顺序相反 package main import "fmt" ...

  7. static & abstract

    不能放在一起的修饰符:final和abstract,private和abstract,static和abstract,因为abstract修饰的方法是必须在其子类中 实现(覆盖),才能以多态方式调用, ...

  8. 记laravel5.5项目php-fpm迁移到swoole4.2.9

    事起说明 最近对上线半年多的laravel项目做了一次少大的改动,由php-fpm改为swoole,这里做个记录. 2019年过年前半个月,上阿里云后台查看前一天的访问请求日志,发现很多接口响应慢.翻 ...

  9. Node.js之Express二

    好久没写了,今天看博客,觉得有必要把node.js继续写完,善始善终.原本想着把小崔课堂继续讲下去,由于其他原因也就此耽搁下来,看看以后还有没有机会吧.废话不扯,123开始. 一.Exoress之Re ...

  10. 一张图看懂Sprint Planning Meeting

    本文主要参考<Scrum精髓>这本书的内容 每个Sprint都是从Sprint Planning Meeting开始,Scrum团队成员聚集在一起商定下个Sprint目标,并且确定在Spr ...