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