在 C# 语言和 .NET 框架中,你能帮助我理解委托(delegate)吗? 我试图检查一些代码,发现我收到的结果出乎我的意料。在这里:
class Program
{
public static int I = 0;
static Func<string> del = new Func<string>(I.ToString);
static void Main(string[] args)
{
I = 10;
Console.WriteLine("{0}", del());
}
}
答案是 0,而不是 10。为什么?
最佳答案
原因如下:
声明委托(delegate)的方式直接指向静态 int 实例的 ToString
方法。它是在创建时捕获的。
正如 flindeberg 在下面的评论中指出的那样,每个委托(delegate)都有一个目标和一个要在目标上执行的方法。
在这种情况下,要执行的方法显然是ToString
方法。有趣的部分是方法执行的实例:它是创建时 I
的实例,这意味着委托(delegate)没有使用 I
来获取要使用的实例,但它存储对实例本身的引用。
稍后您将 I
更改为不同的值,基本上是为它分配一个新实例。这不会神奇地改变您的委托(delegate)中捕获的实例,为什么要这样?
要获得预期的结果,您需要将委托(delegate)更改为:
static Func<string> del = new Func<string>(() => I.ToString());
像这样,委托(delegate)指向一个匿名方法,在委托(delegate)执行的时候,在当前的I
上执行ToString
。
在这种情况下,要执行的方法是在声明委托(delegate)的类中创建的匿名方法。实例为 null,因为它是静态方法。
查看编译器为委托(delegate)的第二个版本生成的代码:
private static Func<string> del = new Func<string>(UserQuery.<.cctor>b__0);
private static string cctor>b__0()
{
return UserQuery.I.ToString();
}
如您所见,这是一个执行某事 的普通方法。在我们的例子中,它返回在 I
的当前实例上调用 ToString
的结果。
关于c# - 在 C# 中使用委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13603795/