什么是“动作”?关键字do,它是否替换ActionResult

tra*_*mer 1 .net c# asp.net-mvc action razor

我看到了这段代码,我想知道该怎么Action?做,在搜索后,我在MSDN上看到了这一点“ 封装了一个具有单个参数并且不返回值的方法。 ”仍然无法理解(应用程序用例)如何使用它,它是ActionResult的更好替代品

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

 public class PrisonerDilemma 
 {
     public string PrisonerName { get; private set; }
     public StrategyBase Strategy { get; private set; }
     // What is this Action keyowrd doing?
     public Action? LastAction { get; private set; }        

     public Prisoner(string name, StrategyBase strategy)
     {
        if (strategy == null)
            throw new ArgumentNullException("strategy");

        PrisonerName = name;
        Strategy = strategy;
     }

     public void Do(Action? previousActionOfAnotherPrisoner)
     {
        if (previousActionOfAnotherPrisoner == null)
            LastAction = Strategy.Init();
        else
            LastAction = Strategy.Next(previousActionOfAnotherPrisoner.Value);
     }

 }
Run Code Online (Sandbox Code Playgroud)

编辑1: 在ASP MVC中

  1. 起什么作用的Action?关键字玩?以及如何使用/利用。
  2. 如果Action不接受参数且不返回值,请帮助说明它的用途,例如,在设计模式中通常何时使用*?将控制器动作传递/引用为子动作?
  3. 如果我想将其用作a VisitorStrategy pattern,是否可以像在C ++中那样跨对象边界传递它?还是范围仅限于实例,类或派生类型?

编辑2:感谢您的解释,它现在很清楚其功能可以重用。我在SO上找到了另一篇文章,该文章有助于理解Action Vs Func之间的区别,而不是典型的用例应用程序,例如实现此目的的好用例。例如在函数重用中,是否可以像在C ++中那样跨对象边界传递它?

Eri*_*sch 5

Action和ActionResult彼此无关。动作与MVC无关。它只是一个泛型委托类型(不是关键字),本质上是一个“模板”,框架决定了创建泛型的用途,因此他们决定创建泛型,以便可以频繁地重用它。

最多可对16个参数采取操作0,所有参数都具有void返回类型。Func相同,但是具有返回类型。

实际上,您可以在需要引用具有类似功能签名的功能的任何地方使用操作。

例如,假设您要创建一个将另一个方法作为参数的方法。可以将这种“其他方法”键入为Action(或Func),这样您就不必对类型进行硬编码。

如果您查看Action文档中的第一个示例,则有一个普通委托函数的示例。第二个示例使用Action来完成相同的操作:

public static void Main()
{
  Action<string> messageTarget; 

  if (Environment.GetCommandLineArgs().Length > 1)
     messageTarget = ShowWindowsMessage;
  else
     messageTarget = Console.WriteLine;

  messageTarget("Hello, World!");   
}      

private static void ShowWindowsMessage(string message)
{
   MessageBox.Show(message);      
}
Run Code Online (Sandbox Code Playgroud)

在此代码中,它引用一个接受1参数和void返回类型的函数。这可以映射到一个动作。 Console.WriteLine()也是采用1个参数和void返回类型的方法,因此如果将它们视为Actions,则它们可以互换。

ActionResult另一方面,是封装从MVC操作返回的数据的类型(不是System.Action)。例如,如果您返回ViewResult,则它从ActionResult派生并封装呈现View所需的数据。它与名称相似的泛型委托Action无关。

编辑:

根据以下评论,您可以使用以下操作来实施预算:

public class MyBudget
{
    int _budgetId;
    int _deptId;
    public MyBudget(int budgetId, int deptId) 
    {
         _budgetId = budgetId;
         _deptId = deptId;
    }
    void CalcBudget()
    {
        // Do your budget code using _budgetId and _deptId
    }
}

public class GenericBudgetProcessor
{
    private Action _specificBudget

    public GenericBudgetProcessor(Action specificBudget)
    {
        _specificBudget = specificBudget;
    }

    public void DoTheBudget(Action specificBudget)
    {
        _specificBudget();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您将在其他地方执行此操作的代码:

var budget = new MyBudget(1, 1);
var processor = new GenericBudgetProcessor(budget.CalcBudget);
processor.DoTheBudget();

// Do a different budget
var budget2 = new YourBudget(2, 2);
processor = new GenericBudgetProcessor(budget2.CalcBudget);
processor.DoTheBudget();
Run Code Online (Sandbox Code Playgroud)

这只是如何使用动作的一个示例。

或者您可以在方法中传递参数

processor.DoTheBudget(1, 2);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可以修改上述内容以使用Action<int, int>而不是Action