上一篇博客主要是对委托和事件做了一小结,这篇是在上一篇博客的基础上对匿名函数和Lambda表达式小结。还是接着上一篇说起,在上一篇中也说了委托是一种数据结构,主要是解决让函数作为参数的问题。在使用委托时首先要声明代理,然后实例化,并将委托对象和已定义好的函数关联上,最后调用。这里与已定义好的函数关联的事情,如果函数是经常使用的也还好,如果不是经常使用的可能只调用一次,那这岂不是老费劲了。就是能不能在使用的时候定义下呢?于是乎有了匿名方法。

一、匿名方法的使用。

匿名方法的使用步骤和委托的使用步骤相同,只是实例化的格式不同。匿名方法的格式:

委托名 实例变量 =delegate(形参列表)

{

};

1.形参列表:参数列表应该和委托声明的匹配。若无可用()表示

2.返回值:返回值也是需要和委托类型的返回值匹配。

二、demo

和委托事件的例子一样,还是定义了一个Person类,并声明了委托EatFoodDelegate。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Delegate
{
//定义了一个从System.Delegate类派生的类
//也可以理解为一种数据类型 这种数据类型指向返回值为void 参数为Person对象的函数
//我们也可以把Person类理解为一种数据类型 只是它包含的是Name和Age
public delegate void EatFoodDelegate(Person p); public class Person
{ public string Name { get; set; } public int Age { get; set; } public Person(string name, int age)
{
Name = name;
Age = age;
} //既然委托是一数据类型和String一样,所以可以像声明String对象一样声明代理变量
public EatFoodDelegate eatFoodDelegate;
////之前是直接声明委托,现在是声明一个事件
//public event EatFoodDelegate EatFoodEventHandler; public void eating()
{ if (eatFoodDelegate != null)
{
eatFoodDelegate(this);
}
} }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Delegate
{
class Program
{
static void Main(string[] args)
{
Person chinesePerson = new Person("小明",);
//通过构造函数实例化对象
chinesePerson.eatFoodDelegate += new EatFoodDelegate(chineseEat);
chinesePerson.eating(); Console.WriteLine("--------------------------------------"); EatFoodDelegate EnglishEatPisaDelegate = delegate (Person p)
{
Console.WriteLine("I'm {0},I am {1} , I eat PiSa", p.Name, p.Age);
}; Person englishPerson = new Person("Ivan",);
englishPerson.eatFoodDelegate = delegate (Person p)
{
Console.WriteLine("I'm {0},I am {1} , I eat MianBao", p.Name, p.Age);
};
englishPerson.eatFoodDelegate += EnglishEatPisaDelegate;
englishPerson.eating();
Console.ReadLine();
}
static void chineseEat(Person p)
{
Console.WriteLine("我是{0},我今年{1}岁了,我吃馒头",p.Name,p.Age);
} } }

在上面代码中可以看到,实例化了两个Person对象,chinesePerson、englishPerson。如果按照上一博客委托的形式还是要new 一个委托对象,将委托和已定义好的函数关联起来。ps:注意委托调用和函数的位置关系。

我们使用匿名方法的方式实现了上一篇博客委托中要实现的功能。只是在englishPerson对象指定委托变量之前先声明了一个匿名方法,这个函数的声明周期也是很短的,然后又声明了一个匿名方法直接赋值给englishPerson的委托。

从上面的两个对象使用委托的比较,我们也可以看出匿名函数的好处。

1.代码结构方面

按照上一博客的方法,委托对象关联已有的方法,这个在代码结构上委托对象和方法是分离的,这个分离主义是代码位置的分离,实例化委托对象可能会在一个方法里面,而关联的方法会是另一个方法,虽然都是在一个类中,但在方法比较多的类中,影响代码检视,查看的时候还要跳转。而在匿名方法中,在调用的时候才会实例化,这样委托方法和调用离得就很近,很容易查看。

2.声明周期

对于一定义的方法,它是定义在类中,而匿名方法则是定义在调用的方法中,声明周期短。对于不经常调用,可能只在这一个地方使用的关联方法,没有必要定义在类中。

三、Lamdba表达式

对于上面的匿名方法还有一个好处就是简洁方便,也主要是帮助有懒癌的小伙伴们,那可能有懒癌到晚期的会问还有没有更简洁方便的能多简洁就多简洁,于是乎Lamdba表达式出现了,它也是匿名方法。下面是它的格式:

(参数列表)=>表达式或语句块

Lambda运算符:所有的lambda表达式都是用新的lambda运算符 " => ",可以叫他,“转到”或者 “成为”。运算符将表达式分为两部分,左边指定输入参数,右边是lambda的主体。还是使用同一个例子稍微改动下代码来说明下Lamdba表达式。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Delegate
{
class Program
{
static void Main(string[] args)
{
Person chinesePerson = new Person("小明",);
//通过构造函数实例化对象
chinesePerson.eatFoodDelegate += new EatFoodDelegate(chineseEat);
chinesePerson.eating(); Console.WriteLine("--------------------------------------"); Person englishPerson = new Person("Ivan",);
englishPerson.eatFoodDelegate = (Person p) => {
Console.WriteLine("I'm {0},I am {1} , I eat MianBao", p.Name, p.Age);
};
englishPerson.eatFoodDelegate += (Person p) => {
Console.WriteLine("I'm {0},I am {1} , I eat PiSa", p.Name, p.Age);
};
englishPerson.eating();
Console.ReadLine();
}
static void chineseEat(Person p)
{
Console.WriteLine("我是{0},我今年{1}岁了,我吃馒头",p.Name,p.Age);
}
}
}

定义Person类就不贴了,上面主要是在englishPerson对象上,上面指定eatFoodDelegate委托的函数是使用Lamdba实现的。可以看到左边是(Person p),右边是代码,中间是Lamdba运算符=>.用上面的与匿名方法的那个demo做比较发现这种方式更为简洁方便。不用再使用delegate关键字创建匿名方法了。

对于泛型委托,就放在泛型部分来了解吧。

C#语法之匿名函数和Lambda表达式的更多相关文章

  1. 浅析匿名函数、lambda表达式、闭包(closure)区别与作用

    浅析匿名函数.lambda表达式.闭包(closure)区别与作用 所有的主流编程语言都对函数式编程有支持,比如c++11.python和java中有lambda表达式.lua和JavaScript中 ...

  2. 3 委托、匿名函数、lambda表达式

    委托.匿名函数.lambda表达式 在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法.C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方 ...

  3. 匿名函数:Lambda表达式和匿名方法

    匿名函数一个"内联"语句或表达式,可在需要委托类型的任何地方使用.可以使用匿名函数来初始化命名委托,或传递命名委托(而不是命名委托类型)作为方法参数. 共有两种匿名函数: Lamb ...

  4. 测开之路八十二:匿名函数:lambda表达式

    # 匿名函数:lambda表达式# lambda 参数: 逻辑f = lambda name: print(name)f('tom') f2 = lambda x, y: x + yprint(f2( ...

  5. [C#学习教程-委托]001.大道至简之委托(代理),匿名函数,Lambda表达式

    引言:此文翻译自CodeProject上的同名文章<C# Delegates,Anonymous Methods, and Lambda Expressions>,在此一起Mark一下,此 ...

  6. 委托,匿名函数和lambda表达式

    很早之前就接触到了委托,但是一直对他用的不是太多,主要是本人是菜鸟,能写的比较高级的代码确实不多,但是最近在看MSDN微软的类库的时候,发现了微软的类库好多都用到了委托,于是决定好好的研究研究,加深一 ...

  7. C++的匿名函数(lambda表达式)

    总述  C++11提供了对匿名函数的支持,称为Lambda函数(也叫Lambda表达式). 它是定义和使用匿名函数对象的一种简便的方式.匿名函数是我们需要用到的一个函数,但是又不想去费力命名一个函数的 ...

  8. 匿名函数、lambda表达式

    匿名函数 func = lambda x: y #x是形参,y是返回值 键字lambda表示匿名函数,冒号前面的x表示函数参数,冒号后面的y表示匿名函数的返回值. 例1:返回列表中长度大于等于3的元素 ...

  9. 委托、匿名函数与Lambda表达式初步

    (以下内容主要来自<C#本质论第三版>第十二章委托和Lambda表达式) 一.委托续 上上周五看了看委托,初步明白了其是个什么,如何定义并调用.上周五准备看Lambda表达式,结果发现C# ...

随机推荐

  1. easyui datagrid sort 表头 排序

    datagrid的点击列表头刷新,分为两种,一种是页面刷新,不涉及后台服务器数据,不会从新查询数据库,只会刷新当前页数据: 一种是服务器级刷新,会重新加载全部数据. 如果不需要自定义排序,可以直接使用 ...

  2. (C#)冒泡排序

    //冒泡排序 public static int[] Bubbling(int[] s) { int a; for (int i = 0; i < s.Length-1; i++) { for ...

  3. Python(IO model)

    day34 IO model 举例:https://blog.csdn.net/ZWE7616175/article/details/80591587 参考:http://www.cnblogs.co ...

  4. FunDA(9)- Stream Source:reactive data streams

    上篇我们讨论了静态数据源(Static Source, snapshot).这种方式只能在预知数据规模有限的情况下使用,对于超大型的数据库表也可以说是不安全的资源使用方式.Slick3.x已经增加了支 ...

  5. 关于finecms v5 会员头像 任意文件上传漏洞分析

    看到我私藏的一个洞被别人提交到补天拿奖金,所以我干脆在社区这里分享,给大家学习下 本文原创作者:常威,本文属i春秋原创奖励计划,未经许可禁止转载! 1.定位功能 下载源码在本地搭建起来后,正常登陆了用 ...

  6. Kafka集群副本分配算法解析

    副本分配算法如下: 将所有N Broker和待分配的i个Partition排序. 将第i个Partition分配到第(i mod n)个Broker上. 将第i个Partition的第j个副本分配到第 ...

  7. jmeter-server中启动后端口总是不断在变化

    1.首先找到这个文件打开: 2.修改两个地方如图: 第一个:server_port=xxxx 第二个:server.rmi.localport=xxxx 3.重启jmeter-server,这是在li ...

  8. 实验三:分别用for、while和do-while循环语句以及递归方法计算n!,并输出算式

    一.用for循环计算n! package for_package; import java.util.*;//导入含有输入类的包 public class for_class { /** * @par ...

  9. redis升级注意事项

    新版本redis读取 旧版本redis的rdb , aof 使用新版本redis备份rdb , aof操作系统级别备份 rdb , aof重启redis测试 新版本redisrdb , aof 能否读 ...

  10. 【xsy1230】 树(tree) 点分治+线段树

    题目大意:有一棵$n$个节点的树,点的标号为$1$到$n$.树中的边有边权.给你$m$个询问,每个询问包含三个参数$l,r,pos$,你要求出标号在$l$到$r$之间的所有点中,到节点$pos$距离最 ...