什么是“行动?”关键字do,它是否取代了ActionResult

时间:2017-03-19 19:27:32

标签: c# .net asp.net-mvc razor action

我看到了这段代码,我想知道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);
     }

 }

编辑1: 在ASP MVC中

  1. Action?关键字的作用是什么??以及如何使用/利用它。
  2. 如果Action不接受参数且不返回值,请帮助解释有什么好处,即什么时候通常在设计模式中使用*?将控制器操作传递给子操作?
  3. 如果我想将它用作VisitorStrategy pattern,它是否可以跨越对象边界传递,就像在C ++中一样?或者范围是否仅限于实例或类或派生类型?
  4. 编辑2: 感谢您的解释,现在很清楚它的功能重用。我发现another post on SO有助于理解Action Vs Func,之间的区别,但不是典型的用例应用程序,就像实现这一点的好用例一样。例如在函数重用中,它是否可以像C ++一样跨对象边界传递?

2 个答案:

答案 0 :(得分:4)

Action和ActionResult彼此无关。动作与MVC无关。它只是一个通用的委托类型(不是关键字),它本质上是一个"模板"他们决定创建泛型类型的框架通常使用它,因此可以经常重复使用。

动作可以在最多16个参数上取0,所有参数都具有void返回类型。 Func是相同的,但有一个返回类型。

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

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

如果你看一下Action documentation中的第一个例子,就会有一个普通委托函数的例子。第二个示例使用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);      
}

在此代码中,它引用一个带有1个参数和void返回类型的函数。这可以映射到Action。 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();
    }
}

然后你会在其他地方有代码来执行此操作:

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();

这只是您如何使用Action的一个示例。

或者您可以传递方法

中的参数
processor.DoTheBudget(1, 2);

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

答案 1 :(得分:3)

Action不是关键字,而是一种类型。 Action类型是委托类型,这意味着它表示对函数的引用。 Action个实例必须引用不带参数的函数并返回void。还有Action的通用版本,如Action<T1, T2>,可用于引用带有多个参数的函数。每个通用参数类型表示一个参数的类型。

https://msdn.microsoft.com/en-us/library/system.action(v=vs.110).aspx

至于类型名称后面的?,这对我来说是错误的。类型之后的?使该类型可为空,但这只能应用于值类型。所有委托类型都是引用类型,因此可以将任何委托指定为null作为值。据我所知,应用于引用类型的?实际上是编译器错误。

以下是ActionResult类型的文档: https://msdn.microsoft.com/en-us/library/system.web.mvc.actionresult(v=vs.118).aspx

此处使用“action”一词与System.Action中的用法完全不同。