c# - 在 C# 中使用委托(delegate)

标签 c# .net delegates

在 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/

相关文章:

C#,xml解析。获取标签之间的数据

javascript - 在 ASP.Net web 表单/MVC 中动态加载和添加字段

.net - 如何通过 Net.WebRequest 正确发送 json 数据 - PowerShell

c# - 从 .NET 3.5 切换到 4 后出错

c# - 在运行 Asp.Net Core 2 的 Webapi 2 上使用 Serilog 的 DI ILogger

c# - Enumerable.Empty<T>() 是代替 foreach 循环中的 null 检查的好选择(C#)?

c# - 如何在 C# 中连接到 .sdf 本地数据库文件

vb.net - Task.Run 与 Task.Factory.StartNew 的返回类型

swift - 让容器 View 上的按钮对不相关的容器 View 执行操作

c# - 委托(delegate)指向什么?