=============================版权申明===============================

  任何人都可以转载,但请注明转载地址和作者“天轰穿”,因为下面这是我正在写的 c# 这本书中的节选内容。

整本书都是这个风格,朋友们有啥期待尽管提。

===========================版权申明结束,内容开始======================

6.3.5 匿名方法

小天:我觉得多少还是有点死板。有不有什么办法可以让委托更灵活,比如某个阶段我并不确定具体要调用的被委托方法名。或者根本不想专门为某个委托就写一个冷僻的方法。

老田:可以使用匿名方法。在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法。C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方法,作为编写内联代码的首选方式。不过,本章讨论的这些内容也同样也适用于 Lambda 表达式(稍后讨论)。有一种情况下,匿名方法提供了 Lambda表达式中所没有的功能。匿名方法使您能够省略参数列表,这意味着可以将匿名方法转换为带有各种签名的委托。这对于 Lambda 表达式来说是不可能的。

要将代码块传递为委托参数,创建匿名方法则是唯一的方法。下面新建一个Windows窗体应用程序,在Form1的设计界面上拖一个button,然后在窗体空白处点右键,查看代码,在Form1的构造函数中编写代码,为button1的click关联一个匿名方法作为执行体,具体Form1的构造函数代码如下:

public Form1()

{

InitializeComponent();

button1.Click += delegate(Object o, EventArgs e)

{

//匿名事件中的代码

MessageBox.Show("按钮事件!");

}; //注意大括号后面有一个分号作为结束

}

然后运行程序。会发现,点击按钮执行的事件就是我们上面写的这个;

小天:匿名方法一定要跟上面示例中这两个参数吗?

老田:当然不是,上面示例之所以要跟这两个参数是因为button的click委托规定了接受他委托的方法的要求是这样的。否则我们也可以像下面这样:

//自定义一个委托类型(注意申明委托的位置,错了别怪我)

delegate void Del(int x);

//申明一个Del委托类型的实例,并为他关联一个匿名类型的匿名事件

Del d = delegate(int k) { /* 方法体 */ };

名方法的优点是减少了要编写的代码。不必定义仅由委托使用的方法。在为事件定义委托时,这是非常显然的。这有助于降低代码的复杂性,尤其是定义了好几个事件时,代码会显得比较简单。使用匿名方法时,代码执行得不太快。编译器仍定义了一个方法,该方法只有一个自动指定的名称,我们不需要知道这个名称。

在使用匿名方法时,必须遵循两个规则。在匿名方法中不能使用跳转语句跳到该匿名方法的外部,反之亦然:匿名方法外部的跳转语句不能跳到该匿名方法的内部。

在匿名方法内部不能访问不安全的代码。另外,也不能访问在匿名方法外部使用的ref和out参数。但可以使用在匿名方法外部定义的其他变量。

如果需要用匿名方法多次编写同一个功能,就不要使用匿名方法。而编写一个指定的方法比较好,因为该方法只需编写一次,以后可通过名称引用它。

6.3.6  Lambda表达式

C# 3.0为匿名方法提供了一个新的语法:Lambda表达式。Lambda表达式可以用于委托类型。“Lambda表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。

所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为“goes to”。该 Lambda 运算符的左边是输入参数(如果有),右边包含表达式或语句块。Lambda 表达式 x => x * x 读作“x goes to x * x”。可以将此表达式分配给委托类型,如下所示:

class Program

{

delegate int del(int i);

static void Main(string[] args)

{

del myDelegate = x => x * x;

int j = myDelegate(5); //j的值为调用委托所得到的值

Console.WriteLine(j);   //值为25

Console.ReadLine();

}

}

现在基本上明白了Lambda表达式的写法,接下来我们结合匿名方法来做一个实例:

class Program

{

delegate int del(int i);

static void Main(string[] args)

{

del myDelegate = x => x * x;

int j = myDelegate(5); //j的值为调用委托所得到的值

Console.WriteLine(j);   //值为25

//注意这里result实际上是del委托类的参数,所以一定是int类型

del d1 = result =>

{

result += 10;   //对传入的result参数做简单处理

return result; //返回结果

}; //注意大括号后面有一个分号作为结束

Console.WriteLine(d1(2));   //直接调用委托,结果显示12

Console.ReadLine();

}

}

老田:给你布置个任务,自定义一个多个参数的委托类型,结合Lambda表达式和匿名方法来做个实例。

小天:等等先问两个问题:

1.                  为什么你上面第一个例题 del myDelegate = x => x * x;  这段代码中 => 符号后面的x * x 没有给大括号,但是第二个是给的大括号?

2.                  多个参数在 => 符号前面怎么表示?

老田:第一个问题:如同if语句一样,如果下面只有一行代码,则可以省略大括号;例如下面这样也是对的

del myDelegate = x =>{return  x * x};

第二个问题:多个参数任然写在=> 符号前面,不过需要用括号括起来,同时多个参数之间用逗号分隔,例如

Del d1 = (x, y, z) => z + y + z;

小天:那就简单了。如下,我定义了一个名为XiaoTian的委托,两个参数,然后在匿名方法中对参数进行了简单的处理,最后返回这里我还做了点举一反三,如下:

class Program

{

//三个参数的委托

delegate string XiaoTian(string xr, int age, string sex);

static void Main(string[] args)

{

//多个参数就必须使用括号,参数之间用逗号分隔

XiaoTian xt = (xr, age, sex) =>

{

StringBuilder jg = new StringBuilder();

jg.Append("小天此人今年");

jg.Append(age);

jg.Append("岁,性别");

jg.Append(sex);

jg.Append(",长相");

jg.Append(xr);

return jg.ToString();   //直接返回结果

};

//调用委托

Console.WriteLine(xt("帅得一塌糊涂", 28, "男"));

Console.ReadLine();

}

}

运行后效果如图6-6

图6-6

老田:不错。上面我们讨论的都是预定义参数的情况下,那么假设传入的参数类型是自定义的类型,恰恰编译器推断不出来怎么办呢?那么接下来就要说到的是在为参数指定类型,如下:

//自定义一个有两个属性的类

class Thc

{

public Thc(string n, int a)

{

Name = n;

Age = a;

}

public string Name { get; set; }

public int Age { get; set; }

}

//控制台应用程序的起始类

class Program

{

//使用自定义类型的参数

delegate string More(Thc t);

static void Main(string[] args)

{

//对参数申明类型

More m =(Thc t )=>

{

return "姓名为" + t.Name + ",年龄" + t.Age;

};

//调用委托,注意所给的参数是新实例一个对象

Console.WriteLine(m(new Thc("天轰穿", 30)));

Console.ReadLine();

}

}

小天:上面说了这么多都是有参数的,如果遇上没有参数的咋办?

老田:没有参数更省事,直接给个空的括号就行,如下:

class Program

{

//无参数

delegate void Wucanshu();

static void Main(string[] args)

{

//对于无参数的情况就直接给一个空的括号就行了

Wucanshu wcs = () =>

{

Console.WriteLine( "我就是无参数,你把我咋样嘛!");

};

//调用委托

wcs();

Console.ReadLine();

}

}

匿名方法和Lambda表达式-天轰穿相关推荐

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

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

  2. [深入学习C#]LINQ查询表达式详解(1)——基本语法、使用扩展方法和Lambda表达式简化LINQ查询

    此文章非原创,转载自诗人江湖老,原文地址 在Git上下载源码 在工程中我们少不了要定义类或者结构去储存数据,这些数据将被临时地储存在内存中,现在我们想要对其完成一些类似于查找.过滤等等常见的任务的时候 ...

  3. JAVA 8 接口中的默认方法和Lambda 表达式基本使用

    一.接口中的默认方法 在JDK1.8之前,interface之中可以定义变量和方法,变量必须是public.static.final的,方法必须是public.abstract的 在JDK 1.8开始 ...

  4. java 8 lambda reduce_java8种的reduce方法和lambda表达式结合使用

    今天碰到了java8种的reduce方法,查了资料之后写一些总结,以免自己以后用到. 计算1,2,3,4,5 的和,并且初始值为3 也就是计算3+1+2+3+4+5 1.使用Stream 两个参数的r ...

  5. C# 从CIL代码了解委托,匿名方法,Lambda 表达式和闭包本质

    前言 C# 3.0 引入了 Lambda 表达式,程序员们很快就开始习惯并爱上这种简洁并极具表达力的函数式编程特性. 本着知其然,还要知其所以然的学习态度,笔者不禁想到了几个问题. (1)匿名函数(匿 ...

  6. Java 回调函数(传统方法和lambda方法)-一个例子秒懂

    原文地址为: Java 回调函数(传统方法和lambda方法)-一个例子秒懂 背景: 想写一个工具类 Tool.java ,其中方法 public void readOneLine() 负责一行一行地 ...

  7. C#语法之匿名函数和Lambda表达式

    上一篇博客主要是对委托和事件做了一小结,这篇是在上一篇博客的基础上对匿名函数和Lambda表达式小结.还是接着上一篇说起,在上一篇中也说了委托是一种数据结构,主要是解决让函数作为参数的问题.在使用委托 ...

  8. C# 委托、匿名委托、Lambda表达式详解

    文章目录 委托 委托概述 声明委托类型 创建委托对象 给委托赋值 组合委托 为委托添加方法 从委托移除方法 调用委托 委托的示例 调用带有返回值的委托 调用带有引用参数的委托 匿名方法 使用匿名方法 ...

  9. C# 匿名委托、匿名方法、匿名对象、Lambda表达式

    C# 匿名委托.匿名方法.匿名对象.Lambda表达式 原文:C# 匿名委托.匿名方法.匿名对象.Lambda表达式 一.匿名类型 可通过使用 new 运算符和对象初始值创建匿名类型. 示例: var ...

  10. Java 8:将匿名类转换为Lambda表达式

    将匿名类(实现一种方法)重构为lambda表达式,可使您的代码更简洁明了. 例如,这是Runnable及其lambda等效项的匿名类: // using an anonymous class Runn ...

最新文章

  1. python java web_Python 与 Java 使用 websocket 通信
  2. JUnit4单元测试报错问题:method initializationerror not found
  3. 二维数组最大子数组和
  4. illegal utf8 encoding at (190)
  5. Pattern类正则表达式的编译表示形式
  6. 【转载】产品经理如何行之有效的提高执行力
  7. [Python Study Notes]pandas.DataFrame.plot()函数绘图
  8. SqlDependency不起作用
  9. 2021年低压电工新版试题及低压电工考试总结
  10. 闺蜜生日c语言代码,祝闺蜜生日快乐的说说大全 2018最新祝朋友生日快乐经典说说...
  11. 2:jdbc 连接步骤及基本用法
  12. HTML <thead> 标签
  13. DES加密解密Delphi、C#互通
  14. CDH安装时报错:/opt/cloudera/parcels/.flood/.../CDH-6.3.2-1.cdh6.3.2.p0.1605554-el7.parcel does not exist
  15. 管理安装软件包yum什么是yum
  16. A Brief History of Humankind — 01 the cognitive revolution
  17. 线下门店如何进行私域运营
  18. 与领导争论问题的技巧[zt]
  19. bugku 杂项 图穷匕见 wp
  20. 个人减肥经验90kg-65kg

热门文章

  1. hadoop常用端口号
  2. matlab 对直方图均衡化,基于直方图均衡化的图像增强技术分析与Matlab实现_直方图均衡化matlab...
  3. CS61A第一章笔记
  4. 爬虫免费Charles使用教程
  5. Unity一键自动将多个FBX文件生成AB包+又一些小玩意
  6. 网络服务器是硬盘吗,云盘与网络服务器硬盘是什么?它们一样吗?
  7. SpringMVC解决POST和GET请求中文乱码问题
  8. ArcMap通过空间校正工具转换BJ-54坐标系到WGS-84坐标系
  9. powerdesigner中cmd模型中多对多_[进行中]美的多多进宝日
  10. 宏晶STC单片机使用STC-ISP串口烧录失败的原因与解决方法汇总