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