C#基础—匿名方法(Anonymous Mehod)

1、引入匿名方法

早在C#
2.0中就提出了匿名方法,实现了以一种内联的方式声明委托,在此之前,声明委托唯一的方法是"命名方法",虽然 C# 3.0 里有了lambda
,使得写内联代码更加简洁和方法,但是匿名方法依然有他的用处,匿名方法提供了可以忽略参数列表的能力。

2、匿名方法的使用和注意点

什么匿名方法?简单的理解就是没有定义名字的方法(其实编译器还是帮我们生成了一个方法)。代码的实现就是把方法的定义和方法的实现内联到了一起。

先看个演示例子:


 1 class Program
2 {
3 static void Main(string[] args)
4 {
5 Thread t1 = new Thread(printMethod);
6 t1.Start();
7
8 Console.Read();
9 }
10
11 static void printMethod()
12 {
13 Console.WriteLine("Start Thread");
14 }
15
16 }

  如果使用匿名方法,就是把方法定义和方法实现内联到一起,避免重新定义命名方法,看Demo:


 1 class Program
2 {
3 static void Main(string[] args)
4 {
5 Thread t1 = new Thread(delegate()
6 {
7 Console.WriteLine("Thread Start");
8 });
9
10 t1.Start();
11
12 Console.Read();
13 }
14 }

这是一个简单使用匿名方法内联委托实例的例子,在使用匿名方法时,有一些注意点如下:

(1)、匿名方法中,外部变量的引用被称为"捕获的外部变量",与本地变量不同,捕获的变量的生存期被扩展或延长,直到引用该匿名方法委托被垃圾回收。

(2)、匿名方法不能访问外部范围的 ref 或 out 参数。

(3)、在"匿名方法块"中不能访问任何不安全代码,即不能使用指针。

(4)、在 is 运算符的左侧不允许使用匿名方法。

这里,需要特别提下的是,匿名方法中的外部变量问题,在使用匿名方法时会形成闭包(closure),与javascript
中的闭包类似。

先看下演示的例子:


 1 public delegate void DelegateDemo();
2
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 DelegateDemo d = TestCaptureVariable();
8 d(); //再次调用
9
10 Console.Read();
11 }
12
13 static DelegateDemo TestCaptureVariable()
14 {
15 //被捕获的外部变量(就是在匿名方法中引用到的变量)
16 int captureVariable = 100;
17 int variable = 101;
18 DelegateDemo d = delegate()
19 {
20 Console.WriteLine(captureVariable);
21 captureVariable = 200;
22 };
23
24 d(); //声明完后直接调用
25 return d;
26 }
28 }

程序输出:

100

200

在本示例程序中,定义了值类型变量captureVariable
,定义在栈上,当第一次调用d(),并结束执行TestCaptureVariable方法后,captureVariable 和 variable
应该被GC回收了,但我们第一次调用d()时,仍然输出了200。

 
  
这种效果就是第一点所说的"捕获变量"的生存周期会因为引用一直存在而被延长。对此,我们可以看下编译器为此做了些什么:

在Program类中多了一个系统自动命名的类,DisplayClass1,这个类里,包含了
captureVariable,其实,编译器对captureVariable,这个匿名方法中的"被捕获变量"
做了一个特别的处理,自动生成了一个类,这个类中包含了该变量,而匿名方法一直保留了对这个类的引用,所以没有被GC回收,所以除了栈上,在其他地方也保存了这个变量,从而导致这个变量并没有被销毁,从而达到了"延长生命周期"的目的。

C#基础—匿名方法(Anonymous Mehod),布布扣,bubuko.com

时间: 2024-10-18 15:51:18

C#基础—匿名方法(Anonymous Mehod)的相关文章

C#学习笔记三: C#2.0泛型 可控类型 匿名方法和迭代器

前言 C#1.0的委托特性使方法作为其他方法的参数来传递,而C#2.0 中提出的泛型特性则使类型可以被参数化,从而不必再为不同的类型提供特殊版本的实现方法.另外C#2.0还提出了可空类型,匿名方法和迭代器3个优美的特性. 1,泛型1.1 泛型是什么泛型的英文表述是"generic", 这个单词意为通用的.从字面意思可知,泛型代表的就是"通用类型",它可以代替任意的数据类型,使类型参数化,从而达到之实现一个方法就可以操作多种数据类型的目的.泛型是将方法实现行为与方法操

[C#] C# 基础回顾 - 匿名方法

C# 基础回顾 - 匿名方法 目录 简介 匿名方法的参数使用范围 委托示例 简介 在 C# 2.0 之前的版本中,我们创建委托的唯一形式 -- 命名方法. 而 C# 2.0 -- 引进了匿名方法,在 ≥ C# 3.0 的版本中,我们会用 Lambda 表达式进行取代匿名方法,并且用 Lambda 表达式作为编写内联代码的首选方式,因为它更简洁. 匿名方法是,顾名思义,匿名方法就是没有名称的方法.匿名方法最明显的好处就是:可以降低额外另写一个方法的工作量:另外一个好处就是可以直接访问调用者的变量,

.net基础扫盲-小例子串委托、匿名方法、lamuda表达式

我把委托理解为:委托是一种方法的格式,当然他也是一种类型. 只要是方法的格式跟委托定义的格式是一样的,那么就可以把该方法附加给该委托.看以下demo 声明委托: <p style="margin:0in;font-family:微软雅黑;font-size:12.0pt"></p><pre name="code" class="csharp">public delegate void Add(int a,int

30天C#基础巩固-----值类型/引用类型,泛型,空合并操作符(??),匿名方法

一:值类型/引用类型的区别      值类型主要包括简单类型,枚举类型,和结构体类型等,值类型的实例通常被分配在线程堆栈上面变量保存的内容是实例数据本身.引用类型被分配在托管堆上,变量保存的是地址.引用类型主要包括类类型,接口类型,委托类型和字符串类型等. 关于参数传递,这里有四种:        值类型参数的按值传递:        引用类型参数按值传递: 关于string引用类型参数按值传递的特殊情况:虽然string类型也是引用类型,然而在按值传递时,传递的实参却不会因方法中形参的改变而被

C#基础知识---匿名方法使用

一.匿名方法使用 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace AnonymousMethod 8 { 9 delegate void DelegateWithoutArguments(); 10 delegate void DelegateWithArgument

委托学习笔记后续:泛型委托及委托中所涉及到匿名方法、Lambda表达式

引言: 最初学习c#时,感觉委托.事件这块很难,其中在学习的过程中还写了一篇学习笔记:委托.事件学习笔记.今天重新温故委托.事件,并且把最近学习到和委托相关的匿名方法.Lambda表达式及泛型委托记录下来,以备复习使用. 委托: 日常工作中,常常见到委托用在具体的项目中.而且委托使用起来相对来说也是非常简单的,下面列举一个委托实例用以说明如何使用委托,代码如下: class Program { public delegate int CalculateDelegate(int x, int y)

C#匿名方法

首先,介绍匿名方法的发展史,以代码展示: static void Main(string[] args) { //最原始的委托 TestDelegate testDelA = new TestDelegate(Method); //C# 2.0 后 Anonymous Method TestDelegate testDelB = delegate(string s) { Console.WriteLine(s); }; //C# 3.0 lambda TestDelegate testDelC

匿名方法中的变量

前面一篇文章看到了C# 2.0中通过匿名方法来简化委托,下面来看看匿名方法中的变量. 闭包和不同的变量类型 闭包的基本概念是:一个函数除了能够通过提供给它的参数与环境交互之外,还能同环境进行更大程度的互动.对于C# 2.0中出现的匿名方法的闭包表现为,匿名方法能使用在声明该匿名方法的方法内部定义的局部变量. 在进一步了解闭包之前,我们先看看下面两个术语: 外部变量(outer variable):是指其作用域(scope)包括一个匿名方法的局部变量或参数(ref和out参数除外) 被捕捉的外部变

javascript匿名方法

首先,看一段很有意思的代码: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>匿名</title> <script type=&qu