委托学习总结(二)匿名方法和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 当你使用委托的时候,有时候是否会感觉到略微有些麻烦,尽管委托已经极大的减少了我们的工作量,比如,有一个方法,只需要使用一次,仅仅是传递给委托,我们就要定义一次他,这未免太 " ...
 
随机推荐
- SPSS学习系列之SPSS Modeler的功能特性(图文详解)
			
不多说,直接上干货! Win7/8/10里如何下载并安装最新稳定版本官网IBM SPSS Modeler 18.0 X64(简体中文 / 英文版)(破解永久使用)(图文详解) 我这里,是以SPSS ...
 - sql 递归树
			
with CTE as ( -->Begin 一个定位点成员 select ID, PersonName,ParentID,cast(PersonName as nvarchar(max)) a ...
 - golang-nsq消息队列应用
			
1. 安装nsq brew install nsq 2.启动nsq https://nsq.io/overview/quick_start.html 3.golang client var produ ...
 - ID3、C4.5和CART决策树对比
			
ID3决策树:利用信息增益来划分节点 信息熵是度量样本集合纯度最常用的一种指标.假设样本集合D中第k类样本所占的比重为pk,那么信息熵的计算则为下面的计算方式 当这个Ent(D)的值越小,说明样本集合 ...
 - lintcode-->哈希函数
			
在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数.一个好的哈希函数可以尽可能少地产生冲突.一种广泛使用的哈希函数算法是使用数值33,假设任何字符串都是基 ...
 - springboot 常用插件
			
热部署 使用run as -java application, 把spring-loader-1.2.4.RELEASE.jar下载下来,放到项目的lib目录中,然后把IDEA的run参数里VM参数设 ...
 - HDFS:分布式文件系统
			
HDFS是GFS的简化版,它同一时刻只允许一个用户对同一文件进行追加写操作(GFS允许并发写).它适合存储大文件,并提供高吞吐量的顺序读/写访问. 它的早期版本两大问题,例如:单点失效和水平扩展不佳. ...
 - Spring Boot 使用Redis
			
转载自:http://www.cnblogs.com/ityouknow/p/5748830.html Redis支持更丰富的数据结构,例如hashes, lists, sets等,同时支持数据持久化 ...
 - lucene源码分析(4)Similarity相似度算法
			
lucene 7.5.0默认的评分Similarity是BM25Similarity (IndexSearcher.java) // the default Similarity private st ...
 - ZOJ 1203 Swordfish(Prim算法求解MST)
			
题目: There exists a world within our world A world beneath what we call cyberspace. A world protected ...