匿名方法求值
运行时对匿名方法表达式的求值将得到一个委托实例,该委托实例引用了这个匿名方法和一组活动的外部变量的集合(可能为空)。当一个由匿名方法表达式求得的委托被调用时,匿名方法体将被执行。方法体中的代码可以使用由委托所引用的一组捕获了的外部变量。
有匿名方法表达式得到的委托的调用链表包含一个唯一的入口点。委托的确切的目标对象和目标方法是未定义的。尤其是委托的目标对象是否为null、函数成员内部的this值或其他对象也是未定义的。
对带有相同的一组(可能为空)捕获的外部变量的语义上一致的匿名方法表达式的求值可以(但不是必须)返回相同的委托实例。这里用的术语“语义上一致的”表示任何情况下对匿名方法的执行对同样的参数应该产生同样的效果。这一规则允许对代码作如下优化:
delegate double Function(double x);
class Test {
static double[] Apply(double[] a, Function f) {
double[] result = new double[a.Length];
for(int i = 0; i < a.Length; i++) result[i] = f(a[i]);
return result;
}
static void F(double[] a, double[] b) {
a = Apply(a, delegate(double x) { return Math.Sin(x); });
b = Apply(b, delegate(double y) { return Math.Sin(y); });
...
}
}
由于两个匿名方法委托具有相同的一组捕获的外部变量(为空),而且匿名方法在语义上是一致的,编译器可以令这两个委托引用一个相同的目标方法。甚至对于这两个匿名方法表达式,编译器可以返回完全一样的委托实例。
委托实例相等性
下面的规则决定着匿名方法委托实例的判等操作符和Object.Equals方法的结果:
从语义上相同的带有相同一组(也可能是都没有没有)被捕获变量的匿名方法表达式(anonymous-method-expressions)所产生的委托实例可以(但不是必须)相等。
从语义上相同的单被捕获变量不同的的匿名方法表达式(anonymous-method-expressions)所产生的委托实例必须不相等。