C#里,派生类的方法里的匿名delegate调用基类的方法会产生无法验证的代码
2009-06-04 08:30:17 来源:WEB开发网用.NET Framework 3.5 Beta 2附带的C#编译器(csc.exe)编译上面的代码,会得到以下警告:
引用
Microsoft (R) Visual C# 2008 Compiler Beta 2 version 3.05.20706.1 for Microsoft (R) .NET Framework version 3.5
版权所有 (C) Microsoft Corporation。保留所有权利。
test1.cs(23,13): warning CS1911: 从匿名方法、lambda表达式、查询表达式或迭代器通过“base”关键字访问成员“Alpha.Blah()”会导致代码无法验证。请考虑将这种访问移入针对包含类型的辅助方法中。
刚装了.NET Framework 3.5的RTM,测试结果一样。至于Mono 1.2.5.1更有趣,完全没有报错。
这里有什么问题呢?Charlie()方法里用this/base去访问自身/基类的成员,不是很正常的么。问题出在C#中应对闭包生成的代码。
在C# 2.0中,引入了匿名delegate的概念,因而可以定义嵌套方法;在C# 3.0中,更进一步引入了Lambda Expression,同样可以用于定义嵌套方法。这里,嵌套的方法的作用域遵守词法作用域,也就是说内部方法可以访问外部包围作用域的变量,包括外部的“this”。外部包围作用域就对嵌套内部方法形成了“闭包”。
由于当一个嵌套方法生成(实例化)后,它的生命周期与它的外部方法不一定相同。它从外部环境中“捕获”到的变量,就像是从外部“逃逸”出来了一样。上面的例子中,Charlie()方法里x和this都成为了逃逸变量。
这些逃逸变量必须与嵌套方法的生命周期相同,即使外部方法已经返回也不能被立即销毁;因此这些逃逸变量也不能在栈上分配。这样,就需要为逃逸变量另外分配空间,常见的做法是在堆上分配。
- ››方法 (Array)
- ››方法和作用域中的内部类
- ››方法调用的绑定
- ››派生线程类
- ››匿名FTP服务器的建立与应用
更多精彩
赞助商链接