在 2.0 之前的 C# 版本中,声明委托的唯一方式是使用命名方法。 C# 2.0 引入匿名方法,在 C# 3.0 及更高版本中,Lambda 表达式取代匿名方法作为编写内联代码的首选方式。 但是,本主题中有关匿名方法的信息也适用于 Lambda 表达式。 在有一种情况下,匿名方法提供 Lambda 表达式中没有的功能。 使用匿名方法可省略参数列表。 这意味着匿名方法可转换为具有多种签名的委托。 Lambda 表达式无法实现这一点。 有关 Lambda 表达式的详细信息,请参阅 Lambda 表达式

创建匿名方法实际上是一种将代码块作为委托参数传递的方式。 这里是两个示例:

// 为单击事件创建处理程序
button1.Click += delegate(System.Object o, System.EventArgs e)
{ System.Windows.Forms.MessageBox.Show("Click!"); };
// 创建一个委托.
delegate void Del(int x); // 使用匿名方法实例化委托
Del d = delegate(int k) { /* ... */ };

由于使用匿名方法无需创建单独的方法,因此可减少对委托进行实例化的编码开销。

例如,在因不得不创建方法而可能出现非必要开销的情况下,指定代码块(而不是委托)很有用处。 开始新线程就是一个很好的示例。 此类创建一个线程,且还包含该线程执行的代码,而无需为委托创建其他方法。

void StartThread()
{
System.Threading.Thread t1 = new System.Threading.Thread
(delegate()
{
System.Console.Write("Hello, ");
System.Console.WriteLine("World!");
});
t1.Start();
}

备注

匿名方法的参数范围为匿名方法块。

如果目标在匿名方法块之外,匿名方法块内具有 gotobreakcontinue 等跳转语句是一种错误。 如果目标在匿名方法块之内,匿名方法块外具有 gotobreakcontinue 等跳转语句也是一种错误。

范围包含匿名方法声明的本地变量和参数称为此匿名方法的外部变量。 例如,在如下代码段中,n 是一个外部变量:

int n = ;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };

创建委托时,对外部变量 n 的引用被视为已捕获。 不同于本地变量,已捕获的变量的生存期一直延伸至引用匿名方法的委托具有垃圾回收资格为止。

匿名方法无法访问外部范围的 inrefout 参数。

无法在匿名方法块内访问任何不安全代码。

不允许在 is 运算符左侧使用匿名方法。

示例

如下示例演示实例化委托的两种方式:

  • 将委托与匿名方法相关联。

  • 将委托与命名方法 (DoWork) 相关联。

在每一种情况下,调用委托时均显示一条消息。

// 定义委托.
delegate void Printer(string s); class TestClass
{
static void Main()
{
// 使用匿名方法实例化委托类型
Printer p = delegate(string j)
{
System.Console.WriteLine(j);
}; // 匿名委托调用的结果
p("The delegate using the anonymous method is called."); // 使用命名方法“DoWork”的委托实例化
p = DoWork; // 传统方式委托调用的结果
p("The delegate using the named method is called.");
} // 与命名委托关联的方法。
static void DoWork(string k)
{
System.Console.WriteLine(k);
}
}
/* 输出:
The delegate using the anonymous method is called.
The delegate using the named method is called.
*/

其他更详细的技术请参考:

C#2.0新增功能03 匿名方法的更多相关文章

  1. C#3.0新增功能03 隐式类型本地变量

    连载目录    [已更新最新开发文章,点击查看详细] 从 Visual C# 3.0 开始,在方法范围内声明的变量可以具有隐式“类型”var. 隐式类型本地变量为强类型,就像用户已经自行声明该类型,但 ...

  2. C#3.0新增功能02 匿名类型

    连载目录    [已更新最新开发文章,点击查看详细] 匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型. 类型名由编译器生成,并且不能在源代码级使用. 每 ...

  3. C#3.0新增功能04 扩展方法

    连载目录    [已更新最新开发文章,点击查看详细] 扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型 ...

  4. C#4.0新增功能03 泛型中的协变和逆变

    连载目录    [已更新最新开发文章,点击查看详细] 协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体 ...

  5. C#3.0新增功能05 分部方法

    连载目录    [已更新最新开发文章,点击查看详细]    分部类或结构可以包含分部方法. 类的一个部分包含方法的签名. 可以在同一部分或另一个部分中定义可选实现. 如果未提供该实现,则会在编译时删除 ...

  6. C#2.0新增功能06 协变和逆变

    连载目录    [已更新最新开发文章,点击查看详细] 在 C# 中,协变和逆变能够实现数组类型.委托类型和泛型类型参数的隐式引用转换. 协变保留分配兼容性,逆变则与之相反. 以下代码演示分配兼容性.协 ...

  7. C#2.0新增功能01 分布类与分部方法

    连载目录    [已更新最新开发文章,点击查看详细] 分部类型 拆分一个类.一个结构.一个接口或一个方法的定义到两个或更多的文件中, 每个源文件包含类型或方法定义的一部分,编译应用程序时将把所有部分组 ...

  8. C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点

    C#基础拾遗系列之二:使用ILSpy探索C#7.0新增功能点   第一部分: C#是一种通用的,类型安全的,面向对象的编程语言.有如下特点: (1)面向对象:c# 是面向对象的范例的一个丰富实现, 它 ...

  9. C#3.0新增功能09 LINQ 基础07 LINQ 中的查询语法和方法语法

    连载目录    [已更新最新开发文章,点击查看详细] 介绍性的语言集成查询 (LINQ) 文档中的大多数查询是使用 LINQ 声明性查询语法编写的.但是在编译代码时,查询语法必须转换为针对 .NET ...

随机推荐

  1. [Erlang-0015][Lager] Erlang日志框架Lager简析

    项目地址:https://github.com/basho/lager (欢迎任何形式的转载,但请务必注明出处:http://www.cnblogs.com/liangjingyang)

  2. file.delete()与file.deleteOnExit(); 的区别

    file.delete()   //删除文件,删除的是创建File对象时指定与之关联创建的那个文件.这是一个立刻执行的操作 file.deleteOnExit();   //在JVM进程退出的时候删除 ...

  3. Model1简介

    Model1模型出现前,整个Web应用的情况:几乎全部由JSP页面组成,JSP页面接收处理客户端请求,对请求处理后直接做出响应. 弊端:在界面层充斥着大量的业务逻辑的代码和数据访问层的代码,Web程序 ...

  4. Qt设置窗体的透明度: setWindowOpacity

    在Qt中,设置窗体透明度的函数有:void   setWindowOpacity(qreal level)   特性: 透明度的有效范围从1.0(完全不透明)到0.0(完全透明的). 默认情况下,此属 ...

  5. Windows10 下运行Linux子系统

    关于Windows10 下运行Linux子系统: Windows10内置Linux子系统初体验:http://www.jianshu.com/p/bc38ed12da1d Win10运行Ubuntu版 ...

  6. js数字转成金额格式

    本文有以下三个段落 1.方法展示 2.方法说明 3.方法实例 1.方法展示 //将数字转换成金额显示 function toMoney(num){ num = num.toFixed(2); num ...

  7. Web框架之Django重要组件(Django中间件、csrf跨站请求伪造)

    Web框架之Django_09 重要组件(Django中间件.csrf跨站请求伪造)   摘要 Django中间件 csrf跨站请求伪造 一.Django中间件: 什么是中间件? 官方的说法:中间件是 ...

  8. Spring-Boot + MyBatis-Plus 踩坑记录

    这两天在学SpringBoot+MyBatis的开发,配置开发环境和DEMO的过程中踩了很多坑,在这里记录一下. 我的开发环境是idea + JDK 1.8.0.211. 首先展示一下demo的项目整 ...

  9. 牛客假日团队赛1 B

    B.便便传送门(一) 题目链接:https://ac.nowcoder.com/acm/contest/918/B 题目 Farmer John最讨厌的农活是运输牛粪.为了精简这个过程,他制造了一个伟 ...

  10. selenium3+python3自动化测试学习之模拟事件处理

    自动化测试实战之ActionChains模拟用户行为 需要模拟鼠标操作才能进行的情况,比如单击.双击.点击鼠标右键.拖拽 解决:selenium提供了一个类来处理这类事件 selenium.webdr ...