在 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. Qt的QWaitCondition(允许线程在一定条件下唤醒其他线程,这样对不间断上传可能比较适用)

    对生产者和消费者问题的另一个解决办法是使用QWaitCondition,它允许线程在一定条件下唤醒其他线程.其中wakeOne()函数在条件满足时随机唤醒一个等待线程,而wakeAll()函数则在条件 ...

  2. Qt Resource系统概说(资源压缩不压缩都可以)

    什么是Qt Resource系统?简单的说,就是在可执行程序中存储binary文件,而且还是与平台无关的. 与Qt Resource系统密切相关的有三个法宝,分别是qmake.rcc.QFile. q ...

  3. UILabel范例实现代码如下

        #import "TWO_ViewController.h" #define SCREEN_Width [[UIScreen mainScreen] bounds].siz ...

  4. C++ Builder 控件的卸载

    控件卸载: 1.选择   BCB   菜单   File→Close   All   (关闭所有文件)     选择BCB   菜单:   Project→Options→Packages   在   ...

  5. Paragon NTFS for Mac 15.5.53 中文破解版(激活码)下载

    Paragon NTFS for Mac中文破解版是一款超级受欢迎的简单.高效.安全的格式读写软件,提供给大家,再也不用到处找Paragon NTFS序列号和Paragon NTFS激活码啦,帮您轻松 ...

  6. 每日一问:到底为什么属性动画后 View 在新位置还能响应事件

    在 Android 开发中,我们难免会使用动画来处理各种各样的动画效果,以满足 UI 的高逼格设计.对于比较复杂的动画效果,我们通常会采用著名的开源库:lottie-android,或许你会对 lot ...

  7. 推荐一个Redis管理工具

    Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理.它支持字符串.哈希表.列表.集合.有序集合,位图,hyperloglogs等数据类型.内置复制.Lu ...

  8. 全网唯一的纯前端实现的canvas支持多图压缩并打包下载的工具

    技术栈: canvas jszip.js(网页端压缩解压缩插件JSZIP库) FileSaver.js(文件保存到本地库) 直接解读源码: <div class="cont" ...

  9. jQuery中ajax-$.getJSON,$.getScript

    jQuery提供了两个特定异步加载的方法$.getJSON()方法和$.getScript()方法 $.getJSON()来加载特定的json文件 $.getScript()来加载特定的javascr ...

  10. java finally块执行时机分析

    java里 finally 关键字通常与try catch块一起使用.用来在方法结束前或发生异常时做一些资源释放的操作.最近也看到网上有一些讨论try catch finally关键词执行的顺序的文章 ...