原因如下:
声明委托的方式直接指向静态int实例的ToString
方法.它在创造时被捕获.
正如弗林德伯格在下面的 comments 中指出的那样,每个委托都有一个目标和一个要在目标上执行的方法.
在本例中,要执行的方法显然是ToString
方法.有趣的部分是在其上执行该方法的实例:它是创建时I
的实例,这意味着委托不是使用I
来获取要使用的实例,而是存储对实例本身的引用.
之后,将I
更改为不同的值,基本上为其分配一个新实例.这并不会神奇地改变代理中捕获的实例,为什么要这样做呢?
要获得预期的结果,需要将代理更改为:
static Func<string> del = new Func<string>(() => I.ToString());
这样,委托指向一个匿名方法,该方法在执行委托时在当前I
上执行ToString
.
在本例中,要执行的方法是在中声明委托的类中创建的匿名方法.实例为空,因为它是一个静态方法.
查看编译器为委托的第二个版本生成的代码:
private static Func<string> del = new Func<string>(UserQuery.<.cctor>b__0);
private static string cctor>b__0()
{
return UserQuery.I.ToString();
}
正如你所看到的,这是一个正常的方法,可以做到something.在我们的例子中,它返回对I
的当前实例调用ToString
的结果.