简体   繁体   English

C#中的动作委托

[英]Action Delegate in C#

I'm having problems getting my head around Action delegates in C# 我在使用C#中的Action代理时遇到了问题

I've looked at this question and I understand the examples there, but in the codebase that I'm working on it's used in a way that I don't quite get. 我已经看了这个问题,并且理解了那里的示例,但是在我正在处理的代码库中,我使用的方式不太了解。 This is the method using the action delegate: 这是使用动作委托的方法:

public static string RenderTemplate<T>(string templatePath, T data)
{
    string result = null;
    ExecuteRazorMethod(() =>
    {
         result = Razor.Run(data, templatePath);
    });
    return result;
}

The call to ExecuteRazorMethod() will invoke the following method: 对ExecuteRazorMethod()的调用将调用以下方法:

private static void ExecuteRazorMethod(Action a)
{
    try
    {
        a();
    }
   .
   .
   .//irrelevant code
   .
}

I don't understand what happens when a() is executed. 我不明白执行a()后会发生什么。 What method is invoked? 调用什么方法? I've tried debugging it, and the value of a passed into the method is : Void <RenderTemplate> b__5 我试过调试它,传递给方法的值是: Void <RenderTemplate> b__5

I don't get that. 我不明白。 I need to know what actually happens to the two parametes in RenderTemplate but not understanding what/where the a() executes makes it hard. 我需要知道RenderTemplate中的两个参数实际发生了什么,但不了解a()执行什么/在哪里执行会变得很困难。 Is it maybe something about Anonymous types that I don't understand? 我可能不了解匿名类型吗?

When a executes in ExecuteRazorMethod , it executes exactly the delegate you pass as a to ExecuteRazorMethod . a在执行ExecuteRazorMethod ,它执行完全代表你传递作为aExecuteRazorMethod Try to toggle the breakpoint at this line result = Razor.Run(data, templatePath); 尝试在此行切换断点result = Razor.Run(data, templatePath); in this piece of code: 在这段代码中:

ExecuteRazorMethod(() =>
{
     result = Razor.Run(data, templatePath);
});

You will see, that when a starts to execute, your breakpoint will hit. 你会看到,当a开始执行时,你的断点就会命中。

That code will be compiled to something more or less similar to this, I hope it becomes clear now: 该代码将被编译为与此类似的东西,我希望现在变得清楚:

[CompilerGenerated]
internal class Closure<T>
{
    public string Result {get; private set;}

    private readonly string _templatePath;
    private readonly T _data;

    public Closure(string templatePath, T data)
    {
      _templatePath = templatePath;
      _data = data;
    }

    public void DelegateMethod()
    {
      Result = Razor.Run(_data, _templatePath);
    }
}

public static string RenderTemplate<T>(string templatePath, T data)
{
    Closure<T> closure = new Closure<T>(templatePath, data);   
    ExecuteRazorMethod(closure);

    return closure.Result;
}

private static void ExecuteRazorMethod<T>(Closure<T> closure)
{
    try
    {
        closure.DelegateMethod();
    }
   .
   .
   .//irrelevant code
   .
}

The compiler actually creates a named method from the 编译器实际上是从。创建一个命名方法

{ result = Razor.Run(data, templatePath); }

part. 部分。 That is the Void <RenderTemplate> b__5 method. 这就是Void <RenderTemplate> b__5方法。 Remember anonymous types and methods are compiler magic (or syntactic sugar if you prefer), ie a C# feature, not a CLR feature. 请记住,匿名类型和方法是编译器的魔力(如果愿意,可以使用语法糖),即C#功能而不是CLR功能。 The compiler has to translate them into something the CLR understands. 编译器必须将它们转换为CLR理解的内容。

When the delegate is created, it captures the data and templatePath variables, so it can access them when it's executed. 创建委托时,它会捕获数据和templatePath变量,因此它可以在执行时访问它们。 That part is commonly known as closure. 该部分通常称为闭包。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM