委托学习总结(二)匿名方法和lambda表达式
之前总结了委托这个困惑着大多初学者的概念,继续来学习匿名方法和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表达式的更多相关文章
- C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=.答案是6个Firs ...
- 写的非常好的文章 C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...
- (转)C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...
- [No0000134]C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...
- 【转】C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...
- C#学习之初步理解委托、事件、匿名方法和Lambda
最经在学习LinqtoSql,然后扯到Lambda表达式,然后扯到匿名方法,然后扯到委托,最后扯到事件处理...后来发现对委托这个概念和事件处理这个过程理解得不是很清晰,遂得一下学习笔记.那里说得不对 ...
- c#委托中的匿名方法和lambda表达式
一.一般委托方式 Func<int, int, int> AddMethodHander; public unName() { AddMethodHander += AddMethod; ...
- 匿名方法和Lambda表达式
匿名方法本质上是一传递给委托的代码块,是使用委托的另一种方法. 规则: 1.匿名方法中不能使用跳转语句跳至次匿名方法的外部,反之亦然:匿名方法外部的跳转语句也不能跳转到匿名方法的内部: 2.在匿名方法 ...
- 匿名方法和Lambda 表达式
Overview 当你使用委托的时候,有时候是否会感觉到略微有些麻烦,尽管委托已经极大的减少了我们的工作量,比如,有一个方法,只需要使用一次,仅仅是传递给委托,我们就要定义一次他,这未免太 " ...
随机推荐
- javac的泛型
?:在实例化对象的时候,不确定泛型参数的具体类型时,可以使用通配符进行对象定义. (1)?表示通配符,通配符 与 T 的区别 T:作用于模板上,用于将数据类型进行参数化,不能用于实例化对象. publ ...
- 【软件工程实践】第二次作业:分布式版本控制系统Git的安装与使用
1.下载安装配置用户名和邮箱. 2. 创建工作目录并通过git init命令把这个目录变成Git可以管理的仓库. 3. 在工作目录下准备文本文件,建议下载Notepad++代替记事本. 4. 组合用g ...
- Jenkins 学习笔记(一)
Jenkins 要学习Jenkins首先要了解一个概念---持续集成,持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成.每次 ...
- pthread和semaphore的简单应用以及四个典型的多线程问题
pthread和semaphore的简单应用以及四个典型的多线程问题 pthread常用函数简单介绍 创建线程 int pthread_create(pthread_t * thread, pt ...
- ABP实战--集成Ladp/AD认证
参照Hunter的ABP-Zero模块中用户管理部分. 由于我们公司的各系统基本都是AD帐号登录的,所以我们需扩展ABP的AuthenticationSource. 添加MyLdapAuthentic ...
- rails跳过回调的方法
rails中的回调可跳过,使用下列方法即可: decrement decrement_counter delete delete_all increment increment_counter tog ...
- JS的可枚举性
在学习ES6的过程中,涉及到遍历方法时,提到过可枚举性,且多种遍历方法都与可枚举性相关.本章节,将总结这些遍历方法的可枚举性,并在必要的部分,给出对比实例. 一.设置属性的可枚举性 在上一文章 ...
- XRP节点部署
目录 XRP节点部署 准备 硬软件配置(建议) 安装Rippled服务 一. 以Stock Server模型运行 在何种情况下运行此模式 二 .以 Validator模式运行 在何种情况下运行此模式 ...
- 原生JavaScript 导出excel表格(兼容ie和其他主流浏览器)
因同事的需求是想前端导出excel表格,网上找了一些demo,自己修改了一下,可能以后会用到,记录下来吧,兼容ie和一些主流浏览器,ie可能会报错,原因参考 这里,edge 浏览器还没有办法导出,正在 ...
- 常用工具说明--jsdoc 前端文档输出工具
1.利用npm安装jsdoc模块 npm install jsdoc -g 2.由于jsdoc默认的生成文档模板不好看,可以下载一套好看些的模板,如 jaguar.js 下载地址:https:// ...