匿名方法总是以一个delegate关键字开始,后面跟着用在方法和方法体(the method body)本身中的参数。正如从上面示例中所见,用户不需要确定匿名方法的返回类型。它(译注:指返回类型)由方法体中的return语句推断而来。.NET CLR不能执行像匿名方法一样的自由流(free flowing)代码块。CLR要求:它执行的每个方法是一个类型的一部分,并且应该是一个静态(static)方法或实例(instance)方法(译注:若一个方法声明中含有 static 修饰符,则称该方法为静态方法。若其中没有 static 修饰符时,则称该方法为实例方法。静态方法不对特定实例进行操作,在静态方法中引用 this 是编译时错误。实例方法对类的某个给定的实例进行操作,而且可以用 this来访问该实例)。因此当你在一个类的代码中写匿名方法并编译这个代码时,C#编译器默默地在你定义匿名方法的相同的类中创建了一个静态或实例方法。所以匿名方法只是一个在类中定义你自己方法以传递到委托(委托处理器/事件处理器)的方便的语法。
当你编译上面的示例时,C#编译器在类''Program''内部即我们定义匿名方法的地方创建了两个private static方法。它此时用这些static方法的地址取代了匿名方法。编译器决定如何创建静态方法或实例方法取决于匿名方法被定义的类中的静态或实例数据成员的用法。在我们的示例中,我们没有用到任何类''Program''的数据成员,因为调用一个静态方法而不是一个实例方法将是高效的,因此C#编译器创建一个static方法来封装我们的匿名方法的代码。下面是这个示例程序集''Program'' 类的ILDASM视图。高亮部分显示了由C#编译器默默添加到''Program''类的新的静态方法。
如果我们已经使用了用匿名方法的''Program'' 类的任何静态数据,C#编译器将仍然在''Program'' 类里创建一个静态方法来包装匿名方法。
匿名方法的实例数据成员用法
让我们在我们的示例中的''Program''类中定义一个新的实例方法,并使用示例类(译注:即''Program''类)一个实例数据成员。下面的代码显示了修改后的示例:
public class Program { public delegate void MyDelegate(); public static void Main(string[] args) { //实例数据成员测试 Program p = new Program(); for(int i=1;i<=5;i++) p.TestInstanceDataMembers(); } public void TestInstanceDataMembers() { MyDelegate d = delegate { Console.WriteLine("Count: {0}",++m_iCount); }; d(); } public int m_iCount = 0; } |
我们定义了一个新的实例方法:TestInstanceDataMembers,在''Program''类中这个方法定义了一个匿名方法,匿名方法使用了实例数据成员:隶属''Program''类的m_iCount。当这个示例编译时,C#编译器将创建一个private实例方法来包装这个在TestInstanceDataMembers中定义的匿名方法。C#编译器必须创建一个实例方法因为该方法需要访问''Program''类的实例数据成员。下面是这个示例程序集''Program''类的ILDASM视图。在图的下部选中部分显示了由C#编译器默默添加到''Program''类的新的private实例方法。